Bug 1529960 - [mozdevice] Retry pidof if no output; r=bc
authorGeoff Brown <gbrown@mozilla.com>
Mon, 25 Feb 2019 20:42:46 +0000
changeset 460980 c3c0216fbb616790d3e2d4141f829765dd160aa0
parent 460979 12aedb95583ab3177a70816eacfd43bd9aa89b4e
child 460981 fae88bb4c6da6cb2c555b8271de4860b13e4378f
push id35613
push usernerli@mozilla.com
push dateTue, 26 Feb 2019 03:52:35 +0000
treeherdermozilla-central@faec87a80ed1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbc
bugs1529960
milestone67.0a1
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
Bug 1529960 - [mozdevice] Retry pidof if no output; r=bc On the Android 7.0 x86_64 emulator, pidof occasionally returns no results for a running process. To guard against this case, mozdevice retries exactly once. Differential Revision: https://phabricator.services.mozilla.com/D20898
testing/mozbase/mozdevice/mozdevice/adb.py
--- a/testing/mozbase/mozdevice/mozdevice/adb.py
+++ b/testing/mozbase/mozdevice/mozdevice/adb.py
@@ -724,18 +724,18 @@ class ADBDevice(ADBCommand):
             self._logger.info("Unable to turn off logcat chatty")
 
         self._selinux = None
         self.enforcing = 'Permissive'
 
         self.version = 0
         while self.version < 1 and (time.time() - start_time) <= float(timeout):
             try:
-                version = self.shell_output("getprop ro.build.version.sdk",
-                                            timeout=timeout)
+                version = self.get_prop("ro.build.version.sdk",
+                                        timeout=timeout)
                 self.version = int(version)
             except ValueError:
                 self._logger.info("unexpected ro.build.version.sdk: '%s'" % version)
                 time.sleep(2)
         if self.version < 1:
             # note slightly different meaning to the ADBTimeoutError here (and above):
             # failed to get valid (numeric) version string in all attempts in allowed time
             raise ADBTimeoutError("ADBDevice: unable to determine ro.build.version.sdk.")
@@ -743,16 +743,24 @@ class ADBDevice(ADBCommand):
         # Do we have pidof?
         if self.version >= version_codes.N:
             self._have_pidof = self.shell_bool("type pidof", timeout=timeout)
         else:
             # unexpected pidof behavior observed on Android 6 in bug 1514363
             self._have_pidof = False
         self._logger.info("Native pidof support: {}".format(self._have_pidof))
 
+        # Bug 1529960 observed pidof intermittently returning no results for a
+        # running process on the 7.0 x86_64 emulator.
+        characteristics = self.get_prop("ro.build.characteristics", timeout=timeout)
+        abi = self.get_prop("ro.product.cpu.abi", timeout=timeout)
+        self._have_flaky_pidof = (self.version == version_codes.N and
+                                  abi == 'x86_64' and
+                                  'emulator' in characteristics)
+
         # Beginning in Android 8.1 /data/anr/traces.txt no longer contains
         # a single file traces.txt but instead will contain individual files
         # for each stack.
         # See https://github.com/aosp-mirror/platform_build/commit/
         # fbba7fe06312241c7eb8c592ec2ac630e4316d55
         stack_trace_dir = self.shell_output("getprop dalvik.vm.stack-trace-dir",
                                             timeout=timeout)
         if not stack_trace_dir:
@@ -831,16 +839,20 @@ class ADBDevice(ADBCommand):
                 self._logger.debug("Check for root adbd failed")
 
     def _pidof(self, appname, timeout=None):
         if self._have_pidof:
             try:
                 pid_output = self.shell_output('pidof %s' % appname, timeout=timeout)
                 re_pids = re.compile(r'[0-9]+')
                 pids = re_pids.findall(pid_output)
+                if self._have_flaky_pidof and not pids:
+                    time.sleep(0.1)
+                    pid_output = self.shell_output('pidof %s' % appname, timeout=timeout)
+                    pids = re_pids.findall(pid_output)
             except ADBError:
                 pids = []
         else:
             procs = self.get_process_list(timeout=timeout)
             # limit the comparion to the first 75 characters due to a
             # limitation in processname length in android.
             pids = [proc[0] for proc in procs if proc[1] == appname[:75]]
         return pids
@@ -1611,17 +1623,17 @@ class ADBDevice(ADBCommand):
         :type timeout: integer or None
         :returns: string ip address of the device or None if it could not
             be found.
         :raises: * ADBTimeoutError
                  * ADBError
         """
         if not interfaces:
             interfaces = ["wlan0", "eth0"]
-            wifi_interface = self.shell_output('getprop wifi.interface', timeout=timeout)
+            wifi_interface = self.get_prop('wifi.interface', timeout=timeout)
             self._logger.debug('get_ip_address: wifi_interface: %s' % wifi_interface)
             if wifi_interface and wifi_interface not in interfaces:
                 interfaces = interfaces.append(wifi_interface)
 
         # ifconfig interface
         # can return two different formats:
         # eth0: ip 192.168.1.139 mask 255.255.255.0 flags [up broadcast running multicast]
         # or
@@ -2045,19 +2057,19 @@ class ADBDevice(ADBCommand):
         # Android 2.3 and later all appear to support ls -R however
         # Nexus 4 does not perform a recursive search on the sdcard
         # unless the path is a directory with * wild card.
         if not recursive:
             recursive_flag = ''
         else:
             recursive_flag = '-R'
             if path.startswith('/sdcard') and path.endswith('/'):
-                model = self.shell_output('getprop ro.product.model',
-                                          timeout=timeout,
-                                          root=root)
+                model = self.get_prop('ro.product.model',
+                                      timeout=timeout,
+                                      root=root)
                 if model == 'Nexus 4':
                     path += '*'
         lines = self.shell_output('%s %s %s' % (self._ls, recursive_flag, path),
                                   timeout=timeout,
                                   root=root).splitlines()
         for line in lines:
             line = line.strip()
             if not line:
@@ -2664,18 +2676,18 @@ class ADBDevice(ADBCommand):
         if 'battery' in directives:
             info['battery'] = self.get_battery_percentage(timeout=timeout)
         if 'disk' in directives:
             info['disk'] = self.shell_output('df /data /system /sdcard',
                                              timeout=timeout).splitlines()
         if 'id' in directives:
             info['id'] = self.command_output(['get-serialno'], timeout=timeout)
         if 'os' in directives:
-            info['os'] = self.shell_output('getprop ro.build.display.id',
-                                           timeout=timeout)
+            info['os'] = self.get_prop('ro.build.display.id',
+                                       timeout=timeout)
         if 'process' in directives:
             ps = self.shell_output('ps', timeout=timeout)
             info['process'] = ps.splitlines()
         if 'systime' in directives:
             info['systime'] = self.shell_output('date', timeout=timeout)
         if 'uptime' in directives:
             uptime = self.shell_output('uptime', timeout=timeout)
             if uptime: