Bug 996443: carry emulator arch automatically for mach commands. r=ahal
authorVicamo Yang <vyang@mozilla.com>
Thu, 01 May 2014 00:57:39 +0800
changeset 181482 c1e8e5bee5ea0ff0b43227a25f536b607940c150
parent 181481 f4c2b896ecbb0be35ed27e281140044bdec359fd
child 181483 876baa06feb9c6cd0bdfcfe8676f613aba95bbce
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersahal
bugs996443
milestone32.0a1
Bug 996443: carry emulator arch automatically for mach commands. r=ahal
layout/tools/reftest/mach_commands.py
testing/marionette/mach_commands.py
testing/mochitest/mach_commands.py
testing/xpcshell/mach_commands.py
--- a/layout/tools/reftest/mach_commands.py
+++ b/layout/tools/reftest/mach_commands.py
@@ -331,20 +331,16 @@ def B2GCommand(func):
     sdcard = CommandArgument('--sdcard', default="10MB",
         help='Define size of sdcard: 1MB, 50MB...etc')
     func = sdcard(func)
 
     emulator_res = CommandArgument('--emulator-res', default='800x1000',
         help='Emulator resolution of the format \'<width>x<height>\'')
     func = emulator_res(func)
 
-    emulator = CommandArgument('--emulator', default='arm',
-        help='Architecture of emulator to use: x86 or arm')
-    func = emulator(func)
-
     marionette = CommandArgument('--marionette', default=None,
         help='host:port to use when connecting to Marionette')
     func = marionette(func)
 
     totalChunks = CommandArgument('--total-chunks', dest='totalChunks',
         help = 'How many chunks to split the tests up into.')
     func = totalChunks(func)
 
@@ -391,17 +387,17 @@ class MachCommands(MachCommandBase):
         reftest = self._spawn(ReftestRunner)
         return reftest.run_desktop_test(test_file, suite=suite, **kwargs)
 
 
 # TODO For now b2g commands will only work with the emulator,
 # they should be modified to work with all devices.
 def is_emulator(cls):
     """Emulator needs to be configured."""
-    return cls.device_name.find('emulator') == 0
+    return cls.device_name.startswith('emulator')
 
 
 @CommandProvider
 class B2GCommands(MachCommandBase):
     def __init__(self, context):
         MachCommandBase.__init__(self, context)
 
         for attr in ('b2g_home', 'xre_path', 'device_name'):
@@ -424,11 +420,18 @@ class B2GCommands(MachCommandBase):
     @Command('crashtest-remote', category='testing',
         description='Run a remote crashtest.',
         conditions=[conditions.is_b2g, is_emulator])
     @B2GCommand
     def run_crashtest_remote(self, test_file, **kwargs):
         return self._run_reftest(test_file, suite='crashtest', **kwargs)
 
     def _run_reftest(self, test_file=None, suite=None, **kwargs):
+        if self.device_name:
+            if self.device_name.startswith('emulator'):
+                emulator = 'arm'
+                if 'x86' in self.device_name:
+                    emulator = 'x86'
+                kwargs['emulator'] = emulator
+
         reftest = self._spawn(ReftestRunner)
         return reftest.run_b2g_test(self.b2g_home, self.xre_path,
             test_file, suite=suite, **kwargs)
--- a/testing/marionette/mach_commands.py
+++ b/testing/marionette/mach_commands.py
@@ -64,26 +64,28 @@ class B2GCommands(MachCommandBase):
     def __init__(self, context):
         MachCommandBase.__init__(self, context)
 
         for attr in ('b2g_home', 'device_name'):
             setattr(self, attr, getattr(context, attr, None))
     @Command('marionette-webapi', category='testing',
         description='Run a Marionette webapi test',
         conditions=[conditions.is_b2g])
-    @CommandArgument('--emulator', choices=['x86', 'arm'],
-        help='Run an emulator of the specified architecture.')
     @CommandArgument('--type', dest='testtype',
         help='Test type, usually one of: browser, b2g, b2g-qemu.',
         default='b2g')
     @CommandArgument('tests', nargs='*', metavar='TESTS',
         help='Path to test(s) to run.')
-    def run_marionette_webapi(self, tests, emulator=None, testtype=None):
-        if not emulator and self.device_name.find('emulator') == 0:
-            emulator='arm'
+    def run_marionette_webapi(self, tests, testtype=None):
+        emulator = None
+        if self.device_name:
+            if self.device_name.startswith('emulator'):
+                emulator = 'arm'
+                if 'x86' in self.device_name:
+                    emulator = 'x86'
 
         if self.substs.get('ENABLE_MARIONETTE') != '1':
             print(MARIONETTE_DISABLED_B2G % 'marionette-webapi')
             return 1
 
         return run_marionette(tests, b2g_path=self.b2g_home, emulator=emulator,
             testtype=testtype, topsrcdir=self.topsrcdir, address=None)
 
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -547,20 +547,16 @@ def B2GCommand(func):
     nowindow = CommandArgument('--no-window', action='store_true', default=False,
         help='Pass --no-window to the emulator')
     func = nowindow(func)
 
     sdcard = CommandArgument('--sdcard', default="10MB",
         help='Define size of sdcard: 1MB, 50MB...etc')
     func = sdcard(func)
 
-    emulator = CommandArgument('--emulator', default='arm',
-        help='Architecture of emulator to use: x86 or arm')
-    func = emulator(func)
-
     marionette = CommandArgument('--marionette', default=None,
         help='host:port to use when connecting to Marionette')
     func = marionette(func)
 
     chunk_total = CommandArgument('--total-chunks', type=int,
         help='Total number of chunks to split tests into.')
     func = chunk_total(func)
 
@@ -654,17 +650,17 @@ class MachCommands(MachCommandBase):
         return mochitest.run_desktop_test(self._mach_context,
             test_paths=test_paths, suite=flavor, **kwargs)
 
 
 # TODO For now b2g commands will only work with the emulator,
 # they should be modified to work with all devices.
 def is_emulator(cls):
     """Emulator needs to be configured."""
-    return cls.device_name.find('emulator') == 0
+    return cls.device_name.startswith('emulator')
 
 
 @CommandProvider
 class B2GCommands(MachCommandBase):
     """So far these are only mochitest plain. They are
     implemented separately because their command lines
     are completely different.
     """
@@ -676,16 +672,22 @@ class B2GCommands(MachCommandBase):
 
     @Command('mochitest-remote', category='testing',
         description='Run a remote mochitest.',
         conditions=[conditions.is_b2g, is_emulator])
     @B2GCommand
     def run_mochitest_remote(self, test_paths, **kwargs):
         from mozbuild.controller.building import BuildDriver
 
+        if self.device_name.startswith('emulator'):
+            emulator = 'arm'
+            if 'x86' in self.device_name:
+                emulator = 'x86'
+            kwargs['emulator'] = emulator
+
         self._ensure_state_subdir_exists('.')
 
         driver = self._spawn(BuildDriver)
         driver.install_tests(remove=False)
 
         mochitest = self._spawn(MochitestRunner)
         return mochitest.run_b2g_test(b2g_home=self.b2g_home,
                 xre_path=self.xre_path, test_paths=test_paths, **kwargs)
--- a/testing/xpcshell/mach_commands.py
+++ b/testing/xpcshell/mach_commands.py
@@ -29,17 +29,20 @@ from mach.decorators import (
 
 ADB_NOT_FOUND = '''
 The %s command requires the adb binary to be on your path.
 
 If you have a B2G build, this can be found in
 '%s/out/host/<platform>/bin'.
 '''.lstrip()
 
-BUSYBOX_URL = 'http://www.busybox.net/downloads/binaries/latest/busybox-armv7l'
+BUSYBOX_URLS = {
+    'arm': 'http://www.busybox.net/downloads/binaries/latest/busybox-armv7l',
+    'x86': 'http://www.busybox.net/downloads/binaries/latest/busybox-i686'
+}
 
 
 if sys.version_info[0] < 3:
     unicode_type = unicode
 else:
     unicode_type = str
 
 # Simple filter to omit the message emitted as a test file begins.
@@ -298,38 +301,41 @@ class B2GXPCShellRunner(MozbuildObject):
         build_path = os.path.join(self.topsrcdir, 'build')
         if build_path not in sys.path:
             sys.path.append(build_path)
 
         self.tests_dir = os.path.join(self.topobjdir, '_tests')
         self.xpcshell_dir = os.path.join(self.tests_dir, 'xpcshell')
         self.bin_dir = os.path.join(self.distdir, 'bin')
 
-    def _download_busybox(self, b2g_home):
-        system_bin = os.path.join(b2g_home, 'out', 'target', 'product', 'generic', 'system', 'bin')
+    def _download_busybox(self, b2g_home, emulator):
+        target_device = 'generic'
+        if emulator == 'x86':
+            target_device = 'generic_x86'
+        system_bin = os.path.join(b2g_home, 'out', 'target', 'product', target_device, 'system', 'bin')
         busybox_path = os.path.join(system_bin, 'busybox')
 
         if os.path.isfile(busybox_path):
             return busybox_path
 
         if not os.path.isdir(system_bin):
             os.makedirs(system_bin)
 
         try:
-            data = urllib2.urlopen(BUSYBOX_URL)
+            data = urllib2.urlopen(BUSYBOX_URLS[emulator])
         except urllib2.URLError:
             print('There was a problem downloading busybox. Proceeding without it,' \
                   'initial setup will be slow.')
             return
 
         with open(busybox_path, 'wb') as f:
             f.write(data.read())
         return busybox_path
 
-    def run_test(self, test_paths, b2g_home=None, busybox=None,
+    def run_test(self, test_paths, b2g_home=None, busybox=None, device_name=None,
                  # ignore parameters from other platforms' options
                  **kwargs):
         try:
             import which
             which.which('adb')
         except which.WhichError:
             # TODO Find adb automatically if it isn't on the path
             print(ADB_NOT_FOUND % ('mochitest-remote', b2g_home))
@@ -343,31 +349,35 @@ class B2GXPCShellRunner(MozbuildObject):
             test_path = self._wrap_path_argument(test_paths[0]).relpath()
 
         import runtestsb2g
         parser = runtestsb2g.B2GOptions()
         options, args = parser.parse_args([])
 
         options.b2g_path = b2g_home
         options.busybox = busybox or os.environ.get('BUSYBOX')
-        options.emulator = 'arm'
         options.localLib = self.bin_dir
         options.localBin = self.bin_dir
         options.logcat_dir = self.xpcshell_dir
         options.manifest = os.path.join(self.xpcshell_dir, 'xpcshell_b2g.ini')
         options.mozInfo = os.path.join(self.topobjdir, 'mozinfo.json')
         options.objdir = self.topobjdir
         options.symbolsPath = os.path.join(self.distdir, 'crashreporter-symbols'),
         options.testingModulesDir = os.path.join(self.tests_dir, 'modules')
         options.testsRootDir = self.xpcshell_dir
         options.testPath = test_path
         options.use_device_libs = True
 
+        options.emulator = 'arm'
+        if device_name.startswith('emulator'):
+            if 'x86' in device_name:
+                options.emulator = 'x86'
+
         if not options.busybox:
-            options.busybox = self._download_busybox(b2g_home)
+            options.busybox = self._download_busybox(b2g_home, options.emulator)
 
         return runtestsb2g.run_remote_xpcshell(parser, options, args)
 
 def is_platform_supported(cls):
     """Must have a Firefox, Android or B2G build."""
     return conditions.is_android(cls) or \
            conditions.is_b2g(cls) or \
            conditions.is_firefox(cls)
@@ -431,16 +441,17 @@ class MachCommands(MachCommandBase):
         driver = self._spawn(BuildDriver)
         driver.install_tests(remove=False)
 
         if conditions.is_android(self):
             xpcshell = self._spawn(AndroidXPCShellRunner)
         elif conditions.is_b2g(self):
             xpcshell = self._spawn(B2GXPCShellRunner)
             params['b2g_home'] = self.b2g_home
+            params['device_name'] = self.device_name
         else:
             xpcshell = self._spawn(XPCShellRunner)
         xpcshell.cwd = self._mach_context.cwd
 
         try:
             return xpcshell.run_test(**params)
         except InvalidTestPathError as e:
             print(e.message)