Backed out 6 changesets (bug 1214812) for kk emulator test bustage
authorWes Kocher <wkocher@mozilla.com>
Tue, 01 Dec 2015 15:33:07 -0800
changeset 309260 82e204405fe5a15aa88b18500131406f1d911f71
parent 309259 047cd783c3e22cdbf9fd8700257ab7b021ab398b
child 309261 76b10dad2e3d3090d73f7911b23dd68243a2d556
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1214812
milestone45.0a1
backs outb36710809f0c945a6b2f3e75304ef3c629940316
a3b5c66f34e4027a3195538f916a26c33ea18b5b
df6d3dc3fca964c88dc9c9c3f62428bbe804396f
9f94be2a3c1d5f570fe31aadc6b6e4ac3e40dbe7
1eaf9f30b00dbaf3eb4846dcc48ef7e8a19d1360
902b985b3273f800bec676ef2e8f9d745bbea15c
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 6 changesets (bug 1214812) for kk emulator test bustage Backed out changeset b36710809f0c (bug 1214812) Backed out changeset a3b5c66f34e4 (bug 1214812) Backed out changeset df6d3dc3fca9 (bug 1214812) Backed out changeset 9f94be2a3c1d (bug 1214812) Backed out changeset 1eaf9f30b00d (bug 1214812) Backed out changeset 902b985b3273 (bug 1214812)
testing/mozbase/mozdevice/mozdevice/adb.py
testing/mozbase/mozdevice/mozdevice/adb_android.py
testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
--- a/testing/mozbase/mozdevice/mozdevice/adb.py
+++ b/testing/mozbase/mozdevice/mozdevice/adb.py
@@ -1,22 +1,21 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # 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/.
 
+from abc import ABCMeta, abstractmethod
 import os
 import posixpath
 import re
 import subprocess
 import tempfile
 import time
 import traceback
 
-from abc import ABCMeta, abstractmethod
-
 
 class ADBProcess(object):
     """ADBProcess encapsulates the data related to executing the adb process."""
     def __init__(self, args):
         #: command argument argument list.
         self.args = args
         #: Temporary file handle to be used for stdout.
         self.stdout_file = tempfile.TemporaryFile()
@@ -531,68 +530,60 @@ class ADBDevice(ADBCommand):
         self._initial_test_root = test_root
         self._test_root = None
         self._device_ready_retry_wait = device_ready_retry_wait
         self._device_ready_retry_attempts = device_ready_retry_attempts
         self._have_root_shell = False
         self._have_su = False
         self._have_android_su = False
 
+        uid = 'uid=0'
+        cmd_id = 'LD_LIBRARY_PATH=/vendor/lib:/system/lib id'
+        # Is shell already running as root?
         # Catch exceptions due to the potential for segfaults
         # calling su when using an improperly rooted device.
+        try:
+            if self.shell_output("id").find(uid) != -1:
+                self._have_root_shell = True
+        except ADBError:
+            self._logger.debug("Check for root shell failed")
 
-        # Note this check to see if adbd is running is performed on
-        # the device in the state it exists in when the ADBDevice is
-        # initialized. It may be the case that it has been manipulated
-        # since its last boot and that its current state does not
-        # match the state the device will have immediately after a
-        # reboot. For example, if adb root was called manually prior
-        # to ADBDevice being initialized, then self._have_root_shell
-        # will not reflect the state of the device after it has been
-        # rebooted again. Therefore this check will need to be
-        # performed again after a reboot.
-
-        self._check_adb_root(timeout=timeout)
-
-        uid = 'uid=0'
         # Do we have a 'Superuser' sh like su?
         try:
-            if self.shell_output("su -c id", timeout=timeout).find(uid) != -1:
+            if self.shell_output("su -c '%s'" % cmd_id).find(uid) != -1:
                 self._have_su = True
-                self._logger.info("su -c supported")
         except ADBError:
-            self._logger.debug("Check for su -c failed")
+            self._logger.debug("Check for su failed")
 
         # Do we have Android's su?
         try:
-            if self.shell_output("su 0 id", timeout=timeout).find(uid) != -1:
+            if self.shell_output("su 0 id").find(uid) != -1:
                 self._have_android_su = True
-                self._logger.info("su 0 supported")
         except ADBError:
-            self._logger.debug("Check for su 0 failed")
+            self._logger.debug("Check for Android su failed")
 
         self._mkdir_p = None
         # Force the use of /system/bin/ls or /system/xbin/ls in case
         # there is /sbin/ls which embeds ansi escape codes to colorize
         # the output.  Detect if we are using busybox ls. We want each
         # entry on a single line and we don't want . or ..
-        if self.shell_bool("/system/bin/ls /", timeout=timeout):
+        if self.shell_bool("/system/bin/ls /"):
             self._ls = "/system/bin/ls"
-        elif self.shell_bool("/system/xbin/ls /", timeout=timeout):
+        elif self.shell_bool("/system/xbin/ls /"):
             self._ls = "/system/xbin/ls"
         else:
             raise ADBError("ADBDevice.__init__: ls not found")
         try:
-            self.shell_output("%s -1A /" % self._ls, timeout=timeout)
+            self.shell_output("%s -1A /" % self._ls)
             self._ls += " -1A"
         except ADBError:
             self._ls += " -a"
 
         # Do we have cp?
-        self._have_cp = self.shell_bool("type cp", timeout=timeout)
+        self._have_cp = self.shell_bool("type cp")
 
         self._logger.debug("ADBDevice: %s" % self.__dict__)
 
     def _get_device_serial(self, device):
         if device is None:
             devices = ADBHost(adb=self._adb_path, adb_host=self._adb_host,
                               adb_port=self._adb_port).devices()
             if len(devices) > 1:
@@ -619,38 +610,16 @@ class ADBDevice(ADBCommand):
         if serial is not None and is_valid_serial(serial):
             return serial
         usb = device.get("usb")
         if usb is not None:
             return "usb:%s" % usb
 
         raise ValueError("Unable to get device serial")
 
-    def _check_adb_root(self, timeout=None):
-        self._have_root_shell = False
-        uid = 'uid=0'
-        # Is shell already running as root?
-        try:
-            if self.shell_output("id", timeout=timeout).find(uid) != -1:
-                self._have_root_shell = True
-                self._logger.info("adbd running as root")
-        except ADBError:
-            self._logger.debug("Check for root shell failed")
-
-        # Do we need to run adb root to get a root shell?
-        try:
-            if (not self._have_root_shell and
-                self.command_output(
-                    ["root"],
-                    timeout=timeout).find("cannot run as root") == -1):
-                self._have_root_shell = True
-                self._logger.info("adbd restarted as root")
-        except ADBError:
-            self._logger.debug("Check for root adbd failed")
-
 
     @staticmethod
     def _escape_command_line(cmd):
         """Utility function to return escaped and quoted version of command
         line.
         """
         quoted_cmd = []
 
@@ -979,25 +948,25 @@ class ADBDevice(ADBCommand):
         with stdout and stderr directed to temporary files. If the
         process takes longer than the specified timeout, the process
         is terminated. The return code is extracted from the stdout
         and is then removed from the file.
 
         It is the caller's responsibilty to clean up by closing
         the stdout and stderr temporary files.
         """
-        if root and not self._have_root_shell:
-            # If root was requested and we do not already have a root
-            # shell, then use the appropriate version of su to invoke
-            # the shell cmd. Prefer Android's su version since it may
-            # falsely report support for su -c.
-            if self._have_android_su:
-                cmd = "su 0 %s" % cmd
+        if root:
+            ld_library_path='LD_LIBRARY_PATH=/vendor/lib:/system/lib'
+            cmd = '%s %s' % (ld_library_path, cmd)
+            if self._have_root_shell:
+                pass
             elif self._have_su:
                 cmd = "su -c \"%s\"" % cmd
+            elif self._have_android_su:
+                cmd = "su 0 \"%s\"" % cmd
             else:
                 raise ADBRootError('Can not run command %s as root!' % cmd)
 
         # prepend cwd and env to command if necessary
         if cwd:
             cmd = "cd %s && %s" % (cwd, cmd)
         if env:
             envstr = '&& '.join(map(lambda x: 'export %s=%s' %
@@ -1886,17 +1855,16 @@ class ADBDevice(ADBCommand):
         self.command_output(["reboot"], timeout=timeout)
         # command_output automatically inserts a 'wait-for-device'
         # argument to adb. Issuing an empty command is the same as adb
         # -s <device> wait-for-device. We don't send an explicit
         # 'wait-for-device' since that would add duplicate
         # 'wait-for-device' arguments which is an error in newer
         # versions of adb.
         self.command_output([], timeout=timeout)
-        self._check_adb_root(timeout=timeout)
         return self.is_device_ready(timeout=timeout)
 
     @abstractmethod
     def is_device_ready(self, timeout=None):
         """Abstract class that returns True if the device is ready.
 
         :param timeout: optional integer specifying the maximum time in
             seconds for any spawned adb process to complete before
--- a/testing/mozbase/mozdevice/mozdevice/adb_android.py
+++ b/testing/mozbase/mozdevice/mozdevice/adb_android.py
@@ -1,18 +1,16 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # 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/.
 
 import os
 import re
 import time
 
-from abc import ABCMeta
-
 import version_codes
 
 from adb import ADBDevice, ADBError
 
 
 class ADBAndroid(ADBDevice):
     """ADBAndroid implements :class:`ADBDevice` providing Android-specific
     functionality.
@@ -21,110 +19,16 @@ class ADBAndroid(ADBDevice):
 
        from mozdevice import ADBAndroid
 
        adbdevice = ADBAndroid()
        print adbdevice.list_files("/mnt/sdcard")
        if adbdevice.process_exist("org.mozilla.fennec"):
            print "Fennec is running"
     """
-    __metaclass__ = ABCMeta
-
-    def __init__(self,
-                 device=None,
-                 adb='adb',
-                 adb_host=None,
-                 adb_port=None,
-                 test_root='',
-                 logger_name='adb',
-                 timeout=300,
-                 verbose=False,
-                 device_ready_retry_wait=20,
-                 device_ready_retry_attempts=3):
-        """Initializes the ADBAndroid object.
-
-        :param device: When a string is passed, it is interpreted as the
-            device serial number. This form is not compatible with
-            devices containing a ":" in the serial; in this case
-            ValueError will be raised.
-            When a dictionary is passed it must have one or both of
-            the keys "device_serial" and "usb". This is compatible
-            with the dictionaries in the list returned by
-            ADBHost.devices(). If the value of device_serial is a
-            valid serial not containing a ":" it will be used to
-            identify the device, otherwise the value of the usb key,
-            prefixed with "usb:" is used.
-            If None is passed and there is exactly one device attached
-            to the host, that device is used. If there is more than one
-            device attached, ValueError is raised. If no device is
-            attached the constructor will block until a device is
-            attached or the timeout is reached.
-        :type device: dict, str or None
-        :param adb_host: host of the adb server to connect to.
-        :type adb_host: str or None
-        :param adb_port: port of the adb server to connect to.
-        :type adb_port: integer or None
-        :param str logger_name: logging logger name. Defaults to 'adb'.
-        :param integer device_ready_retry_wait: number of seconds to wait
-            between attempts to check if the device is ready after a
-            reboot.
-        :param integer device_ready_retry_attempts: number of attempts when
-            checking if a device is ready.
-
-        :raises: * ADBError
-                 * ADBTimeoutError
-                 * ValueError
-        """
-        ADBDevice.__init__(self, device=device, adb=adb,
-                           adb_host=adb_host, adb_port=adb_port,
-                           test_root=test_root,
-                           logger_name=logger_name, timeout=timeout,
-                           verbose=verbose,
-                           device_ready_retry_wait=device_ready_retry_wait,
-                           device_ready_retry_attempts=device_ready_retry_attempts)
-        # https://source.android.com/devices/tech/security/selinux/index.html
-        # setenforce
-        # usage:  setenforce [ Enforcing | Permissive | 1 | 0 ]
-        # getenforce returns either Enforcing or Permissive
-
-        try:
-            self.selinux = True
-            if self.shell_output('getenforce', timeout=timeout) != 'Permissive':
-                self._logger.info('Setting SELinux Permissive Mode')
-                self.shell_output("setenforce Permissive", timeout=timeout, root=True)
-        except ADBError:
-            self.selinux = False
-
-    def reboot(self, timeout=None):
-        """Reboots the device.
-
-        :param timeout: optional integer specifying the maximum time in
-            seconds for any spawned adb process to complete before
-            throwing an ADBTimeoutError.
-            This timeout is per adb call. The total time spent
-            may exceed this value. If it is not specified, the value
-            set in the ADB constructor is used.
-        :raises: * ADBTimeoutError
-                 * ADBError
-
-        reboot() reboots the device, issues an adb wait-for-device in order to
-        wait for the device to complete rebooting, then calls is_device_ready()
-        to determine if the device has completed booting.
-
-        If the device supports running adbd as root, adbd will be
-        restarted running as root. Then, if the device supports
-        SELinux, setenforce Permissive will be called to change
-        SELinux to permissive. This must be done after adbd is
-        restarted in order for the SELinux Permissive setting to
-        persist.
-
-        """
-        ready = ADBDevice.reboot(self, timeout=timeout)
-        self._check_adb_root(timeout=timeout)
-        return ready
 
     # Informational methods
 
     def get_battery_percentage(self, timeout=None):
         """Returns the battery charge as a percentage.
 
         :param timeout: The maximum time in
             seconds for any spawned adb process to complete before
@@ -190,25 +94,20 @@ class ADBAndroid(ADBDevice):
             failure = 'Unknown failure'
             success = True
             try:
                 state = self.get_state(timeout=timeout)
                 if state != 'device':
                     failure = "Device state: %s" % state
                     success = False
                 else:
-                    if (self.selinux and
-                        self.shell_output('getenforce',
-                                          timeout=timeout) != 'Permissive'):
-                        self._logger.info('Setting SELinux Permissive Mode')
-                        self.shell_output("setenforce Permissive", timeout=timeout, root=True)
-                    if self.is_dir(ready_path, timeout=timeout, root=True):
-                        self.rmdir(ready_path, timeout=timeout, root=True)
-                    self.mkdir(ready_path, timeout=timeout, root=True)
-                    self.rmdir(ready_path, timeout=timeout, root=True)
+                    if self.is_dir(ready_path, timeout=timeout):
+                        self.rmdir(ready_path, timeout=timeout)
+                    self.mkdir(ready_path, timeout=timeout)
+                    self.rmdir(ready_path, timeout=timeout)
                     # Invoke the pm list commands to see if it is up and
                     # running.
                     for pm_list_cmd in pm_list_commands:
                         data = self.shell_output("pm list %s" % pm_list_cmd,
                                                  timeout=timeout)
                         if pm_error_string in data:
                             failure = data
                             success = False
--- a/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
+++ b/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
@@ -18,20 +18,18 @@ import mozfile
 class DeviceManagerADB(DeviceManager):
     """
     Implementation of DeviceManager interface that uses the Android "adb"
     utility to communicate with the device. Normally used to communicate
     with a device that is directly connected with the host machine over a USB
     port.
     """
 
-    _haveRootShell = None
-    _haveSu = None
-    _suModifier = None
-    _lsModifier = None
+    _haveRootShell = False
+    _haveSu = False
     _useZip = False
     _logcatNeedsRoot = False
     _pollingInterval = 0.01
     _packageName = None
     _tempDir = None
     connected = False
 
     def __init__(self, host=None, port=5555, retryLimit=5, packageName='fennec',
@@ -67,18 +65,16 @@ class DeviceManagerADB(DeviceManager):
             self._packageName = packageName
 
         # verify that we can run the adb command. can't continue otherwise
         self._verifyADB()
 
         if autoconnect:
             self.connect()
 
-        self._detectLsModifier()
-
     def connect(self):
         if not self.connected:
             # try to connect to the device over tcp/ip if we have a hostname
             if self.host:
                 self._connectRemoteADB()
 
             # verify that we can connect to the device. can't continue
             self._verifyDevice()
@@ -100,32 +96,27 @@ class DeviceManagerADB(DeviceManager):
         if self.host:
             self._disconnectRemoteADB()
 
     def shell(self, cmd, outputfile, env=None, cwd=None, timeout=None, root=False):
         # FIXME: this function buffers all output of the command into memory,
         # always. :(
 
         # If requested to run as root, check that we can actually do that
-        if root:
-            if self._haveRootShell is None and self._haveSu is None:
-                self._checkForRoot()
-            if not self._haveRootShell and not self._haveSu:
-                raise DMError(
-                    "Shell command '%s' requested to run as root but root "
-                    "is not available on this device. Root your device or "
-                    "refactor the test/harness to not require root." %
-                    self._escapedCommandLine(cmd))
+        if root and not self._haveRootShell and not self._haveSu:
+            raise DMError("Shell command '%s' requested to run as root but root "
+                          "is not available on this device. Root your device or "
+                          "refactor the test/harness to not require root." %
+                          self._escapedCommandLine(cmd))
 
         # Getting the return code is more complex than you'd think because adb
         # doesn't actually return the return code from a process, so we have to
         # capture the output to get it
-        if root and self._haveSu:
-            cmdline = "su %s \"%s\"" % (self._suModifier,
-                                        self._escapedCommandLine(cmd))
+        if root and not self._haveRootShell:
+            cmdline = "su -c \"%s\"" % self._escapedCommandLine(cmd)
         else:
             cmdline = self._escapedCommandLine(cmd)
         cmdline += "; echo $?"
 
         # prepend cwd and env to command if necessary
         if cwd:
             cmdline = "cd %s; %s" % (cwd, cmdline)
         if env:
@@ -263,28 +254,26 @@ class DeviceManagerADB(DeviceManager):
             # copytree's target dir must not already exist, so create a subdir
             tmpDirTarget = os.path.join(tmpDir, "tmp")
             shutil.copytree(localDir, tmpDirTarget)
             self._checkCmd(["push", tmpDirTarget, remoteDir],
                            retryLimit=retryLimit, timeout=timeout)
             mozfile.remove(tmpDir)
 
     def dirExists(self, remotePath):
-        data = self._runCmd(["shell", "ls", self._lsModifier, remotePath + '/'],
-                            timeout=self.short_timeout).output
+        data = self._runCmd(["shell", "ls", "-a", remotePath + '/'], timeout=self.short_timeout).output
 
         if len(data) == 1:
             res = data[0]
             if "Not a directory" in res or "No such file or directory" in res:
                 return False
         return True
 
     def fileExists(self, filepath):
-        data = self._runCmd(["shell", "ls", self._lsModifier, filepath],
-                            timeout=self.short_timeout).output
+        data = self._runCmd(["shell", "ls", "-a", filepath], timeout=self.short_timeout).output
         if len(data) == 1:
             foundpath = data[0].decode('utf-8').rstrip()
             if foundpath == filepath:
                 return True
         return False
 
     def removeFile(self, filename):
         if self.fileExists(filename):
@@ -298,32 +287,29 @@ class DeviceManagerADB(DeviceManager):
 
     def moveTree(self, source, destination):
         self._checkCmd(["shell", "mv", source, destination], timeout=self.short_timeout)
 
     def copyTree(self, source, destination):
         self._checkCmd(["shell", "dd", "if=%s" % source, "of=%s" % destination])
 
     def listFiles(self, rootdir):
-        data = self._runCmd(["shell", "ls", self._lsModifier, rootdir],
-                            timeout=self.short_timeout).output
+        data = self._runCmd(["shell", "ls", "-a", rootdir], timeout=self.short_timeout).output
         data[:] = [item.rstrip('\r\n') for item in data]
         if (len(data) == 1):
             if (data[0] == rootdir):
                 return []
             if (data[0].find("No such file or directory") != -1):
                 return []
             if (data[0].find("Not a directory") != -1):
                 return []
             if (data[0].find("Permission denied") != -1):
                 return []
             if (data[0].find("opendir failed") != -1):
                 return []
-            if (data[0].find("Device or resource busy") != -1):
-                return []
         return data
 
     def getProcessList(self):
         p = self._runCmd(["shell", "ps"], timeout=self.short_timeout)
         # first line is the headers
         p.output.pop(0)
         ret = []
         for proc in p.output:
@@ -671,58 +657,43 @@ class DeviceManagerADB(DeviceManager):
             elif deviceStatus != "device":
                 raise DMError("bad status for device %s: %s" % (self._deviceSerial, deviceStatus))
 
         # Check to see if we can connect to device and run a simple command
         if not self._checkCmd(["shell", "echo"], timeout=self.short_timeout) == 0:
             raise DMError("unable to connect to device")
 
     def _checkForRoot(self):
-        self._haveRootShell = False
-        self._haveSu = False
-        # If requested to attempt to run adbd as root, do so before
-        # checking whether adbs is running as root.
-        if self._runAdbAsRoot:
-            self._adb_root()
-
         # Check whether we _are_ root by default (some development boards work
         # this way, this is also the result of some relatively rare rooting
         # techniques)
         proc = self._runCmd(["shell", "id"], timeout=self.short_timeout)
         if proc.output and 'uid=0(root)' in proc.output[0]:
             self._haveRootShell = True
             # if this returns true, we don't care about su
             return
 
         # if root shell is not available, check if 'su' can be used to gain
         # root
-        def su_id(su_modifier, timeout):
-            proc = self._runCmd(["shell", "su", su_modifier, "id"],
-                                timeout=timeout)
+        proc = self._runCmd(["shell", "su", "-c", "id"], timeout=self.short_timeout)
 
-            # wait for response for maximum of 15 seconds, in case su
-            # prompts for a password or triggers the Android SuperUser
-            # prompt
-            start_time = time.time()
-            retcode = None
-            while (time.time() - start_time) <= 15 and retcode is None:
-                retcode = proc.poll()
-            if retcode is None: # still not terminated, kill
-                proc.kill()
+        # wait for response for maximum of 15 seconds, in case su prompts for a
+        # password or triggers the Android SuperUser prompt
+        start_time = time.time()
+        retcode = None
+        while (time.time() - start_time) <= 15 and retcode is None:
+            retcode = proc.poll()
+        if retcode is None: # still not terminated, kill
+            proc.kill()
 
-            if proc.output and 'uid=0(root)' in proc.output[0]:
-                return True
-            return False
+        if proc.output and 'uid=0(root)' in proc.output[0]:
+            self._haveSu = True
 
-        if su_id('0', self.short_timeout):
-            self._haveSu = True
-            self._suModifier = '0'
-        elif su_id('-c', self.short_timeout):
-            self._haveSu = True
-            self._suModifier = '-c'
+        if self._runAdbAsRoot:
+            self._adb_root()
 
     def _isUnzipAvailable(self):
         data = self._runCmd(["shell", "unzip"]).output
         for line in data:
             if (re.search('Usage', line)):
                 return True
         return False
 
@@ -753,23 +724,8 @@ class DeviceManagerADB(DeviceManager):
         """ Some devices require us to reboot adbd as root.
             This function takes care of it.
         """
         if self.processInfo("adbd")[2] != "root":
             self._checkCmd(["root"])
             self._checkCmd(["wait-for-device"])
             if self.processInfo("adbd")[2] != "root":
                 raise DMError("We tried rebooting adbd as root, however, it failed.")
-
-    def _detectLsModifier(self):
-        if self._lsModifier is None:
-            # Check if busybox -1A is required in order to get one
-            # file per line.
-            output = self._runCmd(["shell", "ls", "-1A" "/"],
-                         timeout=self.short_timeout).output
-            output = ' '.join(output)
-            if "Unknown option '-1'. Aborting." in output:
-                self._lsModifier = "-a"
-            elif "-1A/: No such file or directory" in output:
-                self._lsModifier = "-a"
-            else:
-                self._lsModifier = "-1A"
-