Bug 1555141 - Simplify process management in android mozrunner; r=jmaher
authorGeoff Brown <gbrown@mozilla.com>
Tue, 28 May 2019 21:37:42 +0000
changeset 476004 aa6a850c5b9538a3b92b16808a1455f1aac3e712
parent 476003 1fca3309313362e83f3012a488e1bd1d3ff3bc9d
child 476005 2cd983857de6c73d677c161faf1aaa67a4c3f500
push id86591
push usergbrown@mozilla.com
push dateWed, 29 May 2019 04:51:32 +0000
treeherderautoland@aa6a850c5b95 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmaher
bugs1555141
milestone69.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 1555141 - Simplify process management in android mozrunner; r=jmaher There is no real need to use mozprocess from this code, so switched to subprocess. Differential Revision: https://phabricator.services.mozilla.com/D32897
testing/mozbase/mozrunner/mozrunner/devices/android_device.py
--- a/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
@@ -15,17 +15,16 @@ import subprocess
 import sys
 import telnetlib
 import time
 from distutils.spawn import find_executable
 
 import psutil
 import six.moves.urllib as urllib
 from mozdevice import ADBHost, ADBDevice
-from mozprocess import ProcessHandler
 from six.moves.urllib.parse import urlparse
 
 EMULATOR_HOME_DIR = os.path.join(os.path.expanduser('~'), '.mozbuild', 'android-device')
 
 EMULATOR_AUTH_FILE = os.path.join(os.path.expanduser('~'), '.emulator_console_auth_token')
 
 TOOLTOOL_PATH = 'testing/mozharness/external_tools/tooltool.py'
 
@@ -495,44 +494,36 @@ class AndroidEmulator(object):
             _verify_kvm(self.substs)
         if os.path.exists(EMULATOR_AUTH_FILE):
             os.remove(EMULATOR_AUTH_FILE)
             _log_debug("deleted %s" % EMULATOR_AUTH_FILE)
         # create an empty auth file to disable emulator authentication
         auth_file = open(EMULATOR_AUTH_FILE, 'w')
         auth_file.close()
 
-        def outputHandler(line):
-            self.emulator_log.write("<%s>\n" % line)
-            if "Invalid value for -gpu" in line or "Invalid GPU mode" in line:
-                self.gpu = False
-
         env = os.environ
         env['ANDROID_AVD_HOME'] = os.path.join(EMULATOR_HOME_DIR, "avd")
         command = [self.emulator_path, "-avd", self.avd_info.name]
         if self.gpu:
             command += ['-gpu', 'swiftshader_indirect']
         if self.avd_info.extra_args:
             # -enable-kvm option is not valid on OSX and Windows
             if _get_host_platform() in ('macosx64', 'win32') and \
                '-enable-kvm' in self.avd_info.extra_args:
                 self.avd_info.extra_args.remove('-enable-kvm')
             command += self.avd_info.extra_args
         log_path = os.path.join(EMULATOR_HOME_DIR, 'emulator.log')
-        self.emulator_log = open(log_path, 'w')
+        self.emulator_log = open(log_path, 'w+')
         _log_debug("Starting the emulator with this command: %s" %
                    ' '.join(command))
         _log_debug("Emulator output will be written to '%s'" %
                    log_path)
-        self.proc = ProcessHandler(
-            command, storeOutput=False, processOutputLine=outputHandler,
-            stdin=subprocess.PIPE, env=env, ignore_children=True)
-        self.proc.run()
-        _log_debug("Emulator started with pid %d" %
-                   int(self.proc.proc.pid))
+        self.proc = subprocess.Popen(command, env=env, stdin=subprocess.PIPE,
+                                     stdout=self.emulator_log, stderr=self.emulator_log)
+        _log_debug("Emulator started with pid %d" % int(self.proc.pid))
 
     def wait_for_start(self):
         """
            Verify that the emulator is running, the emulator device is visible
            to adb, and Android has booted.
         """
         if not self.proc:
             _log_warning("Emulator not started!")
@@ -576,17 +567,26 @@ class AndroidEmulator(object):
             return False
         if self.avd_info.x86:
             _log_info("Running the x86 emulator; be sure to install an x86 APK!")
         else:
             _log_info("Running the arm emulator; be sure to install an arm APK!")
         return True
 
     def check_completed(self):
-        if self.proc.proc.poll() is not None:
+        if self.proc.poll() is not None:
+            if self.gpu:
+                try:
+                    for line in self.emulator_log.readlines():
+                        if "Invalid value for -gpu" in line or "Invalid GPU mode" in line:
+                            self.gpu = False
+                            break
+                except Exception as e:
+                    _log_warning(str(e))
+
             if not self.gpu and not self.restarted:
                 _log_warning("Emulator failed to start. Your emulator may be out of date.")
                 _log_warning("Trying to restart the emulator without -gpu argument.")
                 self.restarted = True
                 self.start()
                 return False
             _log_warning("Emulator has already completed!")
             log_path = os.path.join(EMULATOR_HOME_DIR, 'emulator.log')
@@ -666,17 +666,17 @@ class AndroidEmulator(object):
                     _log_warning("Unable to connect to port 5554")
             except Exception:
                 _log_warning("Trying again after unexpected exception")
             finally:
                 if tn is not None:
                     tn.close()
             if not telnet_ok:
                 time.sleep(10)
-                if self.proc.proc.poll() is not None:
+                if self.proc.poll() is not None:
                     _log_warning("Emulator has already completed!")
                     return False
         return telnet_ok
 
     def _get_avd_type(self, requested):
         if requested in AVD_DICT.keys():
             return requested
         if self.substs:
@@ -815,31 +815,24 @@ def _get_tooltool_manifest(substs, src_p
             copied = True
             _log_debug("Copied tooltool manifest %s to %s" % (src, dst))
     if not copied:
         url = os.path.join(TRY_URL, src_path)
         _download_file(url, filename, dst_path)
 
 
 def _tooltool_fetch():
-    def outputHandler(line):
-        _log_debug(line)
-
     tooltool_full_path = os.path.abspath(TOOLTOOL_PATH)
     command = [sys.executable, tooltool_full_path,
                'fetch', '-o', '-m', 'releng.manifest']
-    proc = ProcessHandler(
-        command, processOutputLine=outputHandler, storeOutput=False,
-        cwd=EMULATOR_HOME_DIR)
-    proc.run()
     try:
-        proc.wait()
-    except Exception:
-        if proc.poll() is None:
-            proc.kill(signal.SIGTERM)
+        response = subprocess.check_output(command, cwd=EMULATOR_HOME_DIR)
+        _log_debug(response)
+    except Exception as e:
+        _log_warning(str(e))
 
 
 def _get_host_platform():
     plat = None
     if 'darwin' in str(sys.platform).lower():
         plat = 'macosx64'
     elif 'win32' in str(sys.platform).lower():
         plat = 'win32'
@@ -899,18 +892,15 @@ def _verify_kvm(substs):
     # 0
     # KVM (version 12) is installed and usable
     # accel
     emulator_path = _find_sdk_exe(substs, 'emulator', True)
     if not emulator_path:
         emulator_path = 'emulator'
     command = [emulator_path, '-accel-check']
     try:
-        p = ProcessHandler(command, storeOutput=True)
-        p.run()
-        p.wait()
-        out = p.output
+        out = subprocess.check_output(command)
         if 'is installed and usable' in ''.join(out):
             return
     except Exception as e:
         _log_warning(str(e))
     _log_warning("Unable to verify kvm acceleration!")
     _log_warning("The x86 emulator may fail to start without kvm.")