Bug 1064004 - Pre: Allow running Android emulators in headless mode. r?gbrown draft
authorNick Alexander <nalexander@mozilla.com>
Sun, 28 Feb 2016 13:42:29 -0800
changeset 338755 2b6ab550e591828aae65176c25776a9b09994832
parent 338754 3282a189323c8ea9d2f5ae52e18a2cb4f50873c8
child 338756 a068e9be4d853f3e9f5f4e08e985788efbd00cb2
push id12579
push usernalexander@mozilla.com
push dateWed, 09 Mar 2016 23:56:43 +0000
reviewersgbrown
bugs1064004
milestone48.0a1
Bug 1064004 - Pre: Allow running Android emulators in headless mode. r?gbrown MozReview-Commit-ID: 4b0YySqMG3w
mobile/android/mach_commands.py
testing/mozbase/mozrunner/mozrunner/devices/android_device.py
--- a/mobile/android/mach_commands.py
+++ b/mobile/android/mach_commands.py
@@ -101,17 +101,19 @@ class AndroidEmulatorCommands(MachComman
         help='Specify Android version to run in emulator. One of "2.3", "4.3", or "x86".',
         default='4.3')
     @CommandArgument('--wait', action='store_true',
         help='Wait for emulator to be closed.')
     @CommandArgument('--force-update', action='store_true',
         help='Update AVD definition even when AVD is already installed.')
     @CommandArgument('--verbose', action='store_true',
         help='Log informative status messages.')
-    def emulator(self, version, wait=False, force_update=False, verbose=False):
+    @CommandArgument('--headless', action='store_true',
+        help='Do not require audio, window, or GPU.')
+    def emulator(self, version, wait=False, force_update=False, verbose=False, headless=False):
         from mozrunner.devices.android_device import AndroidEmulator
 
         emulator = AndroidEmulator(version, verbose, substs=self.substs, device_serial='emulator-5554')
         if emulator.is_running():
             # It is possible to run multiple emulators simultaneously, but:
             #  - if more than one emulator is using the same avd, errors may
             #    occur due to locked resources;
             #  - additional parameters must be specified when running tests,
@@ -131,17 +133,17 @@ class AndroidEmulatorCommands(MachComman
         if not emulator.check_avd(force_update):
             self.log(logging.INFO, "emulator", {},
                      "Fetching and installing AVD. This may take a few minutes...")
             emulator.update_avd(force_update)
 
         self.log(logging.INFO, "emulator", {},
                  "Starting Android emulator running %s..." %
                  emulator.get_avd_description())
-        emulator.start()
+        emulator.start(headless=headless)
         if emulator.wait_for_start():
             self.log(logging.INFO, "emulator", {},
                      "Android emulator is running.")
         else:
             # This is unusual but the emulator may still function.
             self.log(logging.WARN, "emulator", {},
                      "Unable to verify that emulator is running.")
 
--- a/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
@@ -30,21 +30,22 @@ MANIFEST_PATH = 'testing/config/tooltool
 
 verbose_logging = False
 
 class AvdInfo(object):
     """
        Simple class to contain an AVD description.
     """
     def __init__(self, description, name, tooltool_manifest, extra_args,
-                 port, uses_sut, sut_port, sut_port2):
+                 headless_args, port, uses_sut, sut_port, sut_port2):
         self.description = description
         self.name = name
         self.tooltool_manifest = tooltool_manifest
         self.extra_args = extra_args
+        self.headless_args = headless_args
         self.port = port
         self.uses_sut = uses_sut
         self.sut_port = sut_port
         self.sut_port2 = sut_port2
 
 
 """
    A dictionary to map an AVD type to a description of that type of AVD.
@@ -54,33 +55,36 @@ class AvdInfo(object):
 """
 AVD_DICT = {
     '2.3': AvdInfo('Android 2.3',
                    'mozemulator-2.3',
                    'testing/config/tooltool-manifests/androidarm/releng.manifest',
                    ['-debug',
                     'init,console,gles,memcheck,adbserver,adbclient,adb,avd_config,socket',
                     '-qemu', '-m', '1024', '-cpu', 'cortex-a9'],
+                   ['-no-audio', '-no-window', '-gpu', 'off'],
                    5554,
                    True,
                    20701, 20700),
     '4.3': AvdInfo('Android 4.3',
                    'mozemulator-4.3',
                    'testing/config/tooltool-manifests/androidarm_4_3/releng.manifest',
                    ['-show-kernel', '-debug',
                     'init,console,gles,memcheck,adbserver,adbclient,adb,avd_config,socket'],
+                   ['-no-audio', '-no-window', '-gpu', 'off'],
                    5554,
                    False,
                    0, 0),
     'x86': AvdInfo('Android 4.2 x86',
                    'mozemulator-x86',
                    'testing/config/tooltool-manifests/androidx86/releng.manifest',
                    ['-debug',
                     'init,console,gles,memcheck,adbserver,adbclient,adb,avd_config,socket',
                     '-qemu', '-m', '1024', '-enable-kvm'],
+                   ['-no-audio', '-no-window', '-gpu', 'off'],
                    5554,
                    False,
                    0, 0)
 }
 
 def verify_android_device(build_obj, install=False, xre=False, debugger=False):
     """
        Determine if any Android device is connected via adb.
@@ -373,31 +377,33 @@ class AndroidEmulator(object):
         if force and os.path.exists(avd):
             shutil.rmtree(avd)
         if not os.path.exists(avd):
             url = '%s/%s' % (TRY_URL, self.avd_info.tooltool_manifest)
             _download_file(url, 'releng.manifest', EMULATOR_HOME_DIR)
             _tooltool_fetch()
             self._update_avd_paths()
 
-    def start(self):
+    def start(self, headless=False):
         """
            Launch the emulator.
         """
         def outputHandler(line):
             self.emulator_log.write("<%s>\n" % line)
         env = os.environ
         env['ANDROID_AVD_HOME'] = os.path.join(EMULATOR_HOME_DIR, "avd")
         command = [self.emulator_path, "-avd",
                    self.avd_info.name, "-port", "5554"]
         if self.avd_info.extra_args:
             # -enable-kvm option is not valid on OSX
             if _get_host_platform() == 'macosx64' and '-enable-kvm' in self.avd_info.extra_args:
                 self.avd_info.extra_args.remove('-enable-kvm')
             command += self.avd_info.extra_args
+        if headless:
+            command += self.avd_info.headless_args
         log_path = os.path.join(EMULATOR_HOME_DIR, 'emulator.log')
         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,