Bug 1635563 - Initial kaios support for 'mach xpcshell-test'; r=bc
authorGeoff Brown <gbrown@mozilla.com>
Fri, 15 May 2020 15:19:30 +0000
changeset 530352 775e1e4cba9d66b077b021fb251eda421cf2d140
parent 530351 6e26d23f6b5e65fa39c60aaaa84330a585375222
child 530353 decc13d5e0971467b714f65952251753c8f660d5
push id116125
push usergbrown@mozilla.com
push dateFri, 15 May 2020 17:24:10 +0000
treeherderautoland@775e1e4cba9d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbc
bugs1635563
milestone78.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 1635563 - Initial kaios support for 'mach xpcshell-test'; r=bc Support 'mach xpcshell-test' in a KaiOS environment. This is very much like running xpcshell in an android/geckoview environment except instead of using an APK for the gre, it uses the omnijar. Differential Revision: https://phabricator.services.mozilla.com/D75545
testing/xpcshell/mach_commands.py
testing/xpcshell/remotexpcshelltests.py
--- a/testing/xpcshell/mach_commands.py
+++ b/testing/xpcshell/mach_commands.py
@@ -183,17 +183,19 @@ class AndroidXPCShellRunner(MozbuildObje
             kwargs["mozInfo"] = os.path.join(self.topobjdir, 'mozinfo.json')
 
         if not kwargs["manifest"]:
             kwargs["manifest"] = os.path.join(self.topobjdir, '_tests/xpcshell/xpcshell.ini')
 
         if not kwargs["symbolsPath"]:
             kwargs["symbolsPath"] = os.path.join(self.distdir, 'crashreporter-symbols')
 
-        if not kwargs["localAPK"]:
+        if self.substs.get('MOZ_BUILD_APP') == 'b2g':
+            kwargs["localAPK"] = None
+        elif not kwargs["localAPK"]:
             for root, _, paths in os.walk(os.path.join(kwargs["objdir"], "gradle")):
                 for file_name in paths:
                     if (file_name.endswith(".apk") and
                         file_name.startswith("geckoview-withGeckoBinaries")):
                         kwargs["localAPK"] = os.path.join(root, file_name)
                         print("using APK: %s" % kwargs["localAPK"])
                         break
                 if kwargs["localAPK"]:
@@ -211,17 +213,17 @@ class AndroidXPCShellRunner(MozbuildObje
 
         self.log_manager.disable_unstructured()
 
         return int(not result)
 
 
 def get_parser():
     build_obj = MozbuildObject.from_environment(cwd=here)
-    if conditions.is_android(build_obj):
+    if conditions.is_android(build_obj) or build_obj.substs.get('MOZ_BUILD_APP') == 'b2g':
         return parser_remote()
     else:
         return parser_desktop()
 
 
 @CommandProvider
 class MachCommands(MachCommandBase):
     @Command('xpcshell-test', category='testing',
@@ -252,17 +254,17 @@ class MachCommands(MachCommandBase):
                 "verbose": True
             }
             params['log'] = structured.commandline.setup_logging(
                 "XPCShellTests", params, log_defaults, fmt_defaults)
 
         if not params['threadCount']:
             params['threadCount'] = int((cpu_count() * 3) / 2)
 
-        if conditions.is_android(self):
+        if conditions.is_android(self) or self.substs.get('MOZ_BUILD_APP') == 'b2g':
             from mozrunner.devices.android_device import verify_android_device, get_adb_path
             device_serial = params.get('deviceSerial')
             verify_android_device(self, network=True, device_serial=device_serial)
             if not params['adbPath']:
                 params['adbPath'] = get_adb_path(self)
             xpcshell = self._spawn(AndroidXPCShellRunner)
         else:
             xpcshell = self._spawn(XPCShellRunner)
--- a/testing/xpcshell/remotexpcshelltests.py
+++ b/testing/xpcshell/remotexpcshelltests.py
@@ -140,20 +140,24 @@ class RemoteXPCShellTestThread(xpcshell.
         # change base class' paths to remote paths and use base class to build command
         self.xpcshell = posixpath.join(self.remoteBinDir, "xpcw")
         self.headJSPath = posixpath.join(self.remoteScriptsDir, 'head.js')
         self.httpdJSPath = posixpath.join(self.remoteComponentsDir, 'httpd.js')
         self.httpdManifest = posixpath.join(self.remoteComponentsDir, 'httpd.manifest')
         self.testingModulesDir = self.remoteModulesDir
         self.testharnessdir = self.remoteScriptsDir
         xpcsCmd = xpcshell.XPCShellTestThread.buildXpcsCmd(self)
-        # remove "-g <dir> -a <dir>" and add "--greomni <apk>"
+        # remove "-g <dir> -a <dir>" and replace with remote alternatives
         del xpcsCmd[1:5]
-        xpcsCmd.insert(3, '--greomni')
-        xpcsCmd.insert(4, self.remoteAPK)
+        if self.options['localAPK']:
+            xpcsCmd.insert(3, '--greomni')
+            xpcsCmd.insert(4, self.remoteAPK)
+        else:
+            xpcsCmd.insert(1, '-g')
+            xpcsCmd.insert(2, self.remoteBinDir)
 
         if self.remoteDebugger:
             # for example, "/data/local/gdbserver" "localhost:12345"
             xpcsCmd = [self.remoteDebugger, self.remoteDebuggerArgs] + xpcsCmd
         return xpcsCmd
 
     def killTimeout(self, proc):
         self.kill(proc)
@@ -288,25 +292,28 @@ class XPCShellRemote(xpcshell.XPCShellTe
         if options['objdir']:
             self.xpcDir = os.path.join(options['objdir'], "_tests/xpcshell")
         elif os.path.isdir(os.path.join(here, 'tests')):
             self.xpcDir = os.path.join(here, 'tests')
         else:
             print("Couldn't find local xpcshell test directory", file=sys.stderr)
             sys.exit(1)
 
-        self.localAPKContents = ZipFile(options['localAPK'])
+        self.remoteAPK = None
+        if options['localAPK']:
+            self.localAPKContents = ZipFile(options['localAPK'])
+            self.remoteAPK = posixpath.join(self.remoteBinDir,
+                                            os.path.basename(options['localAPK']))
+        else:
+            self.localAPKContents = None
         if options['setup']:
             self.setupTestDir()
             self.setupUtilities()
             self.setupModules()
         self.initDir(self.remoteMinidumpDir)
-        self.remoteAPK = None
-        self.remoteAPK = posixpath.join(self.remoteBinDir,
-                                        os.path.basename(options['localAPK']))
 
         # data that needs to be passed to the RemoteXPCShellTestThread
         self.mobileArgs = {
             'device': self.device,
             'remoteBinDir': self.remoteBinDir,
             'remoteScriptsDir': self.remoteScriptsDir,
             'remoteComponentsDir': self.remoteComponentsDir,
             'remoteModulesDir': self.remoteModulesDir,
@@ -381,37 +388,38 @@ class XPCShellRemote(xpcshell.XPCShellTe
         abi = None
         retries = 0
         while not abi and retries < 3:
             abi = self.device.get_prop("ro.product.cpu.abi")
             retries += 1
         if not abi:
             raise Exception("failed to get ro.product.cpu.abi from device")
         self.log.info("ro.product.cpu.abi %s" % abi)
-        abilist = [abi]
-        retries = 0
-        while not abilistprop and retries < 3:
-            abilistprop = self.device.get_prop("ro.product.cpu.abilist")
-            retries += 1
-        self.log.info('ro.product.cpu.abilist %s' % abilistprop)
-        abi_found = False
-        names = [n for n in self.localAPKContents.namelist() if n.startswith('lib/')]
-        self.log.debug("apk names: %s" % names)
-        if abilistprop and len(abilistprop) > 0:
-            abilist.extend(abilistprop.split(','))
-        for abicand in abilist:
-            abi_found = len([n for n in names if n.startswith('lib/%s' % abicand)]) > 0
-            if abi_found:
-                abi = abicand
-                break
-        if not abi_found:
-            self.log.info("failed to get matching abi from apk.")
-            if len(names) > 0:
-                self.log.info("device cpu abi not found in apk. Using abi from apk.")
-                abi = names[0].split('/')[1]
+        if self.localAPKContents:
+            abilist = [abi]
+            retries = 0
+            while not abilistprop and retries < 3:
+                abilistprop = self.device.get_prop("ro.product.cpu.abilist")
+                retries += 1
+            self.log.info('ro.product.cpu.abilist %s' % abilistprop)
+            abi_found = False
+            names = [n for n in self.localAPKContents.namelist() if n.startswith('lib/')]
+            self.log.debug("apk names: %s" % names)
+            if abilistprop and len(abilistprop) > 0:
+                abilist.extend(abilistprop.split(','))
+            for abicand in abilist:
+                abi_found = len([n for n in names if n.startswith('lib/%s' % abicand)]) > 0
+                if abi_found:
+                    abi = abicand
+                    break
+            if not abi_found:
+                self.log.info("failed to get matching abi from apk.")
+                if len(names) > 0:
+                    self.log.info("device cpu abi not found in apk. Using abi from apk.")
+                    abi = names[0].split('/')[1]
         self.log.info("Using abi %s." % abi)
         self.env["MOZ_ANDROID_CPU_ABI"] = abi
 
     def setupUtilities(self):
         self.initDir(self.remoteTmpDir)
         self.initDir(self.remoteBinDir)
         remotePrefDir = posixpath.join(self.remoteBinDir, "defaults", "pref")
         self.initDir(posixpath.join(remotePrefDir, "extra"))
@@ -450,22 +458,30 @@ class XPCShellRemote(xpcshell.XPCShellTe
         self.device.push(local, remoteFile)
         self.device.chmod(remoteFile, root=True)
 
         local = os.path.join(self.localBin, "components/httpd.manifest")
         remoteFile = posixpath.join(self.remoteComponentsDir, "httpd.manifest")
         self.device.push(local, remoteFile)
         self.device.chmod(remoteFile, root=True)
 
-        remoteFile = posixpath.join(self.remoteBinDir,
-                                    os.path.basename(self.options['localAPK']))
-        self.device.push(self.options['localAPK'], remoteFile)
-        self.device.chmod(remoteFile, root=True)
+        if self.options['localAPK']:
+            remoteFile = posixpath.join(self.remoteBinDir,
+                                        os.path.basename(self.options['localAPK']))
+            self.device.push(self.options['localAPK'], remoteFile)
+            self.device.chmod(remoteFile, root=True)
 
-        self.pushLibs()
+            self.pushLibs()
+        else:
+            localB2G = os.path.join(self.options['objdir'], "dist", "b2g")
+            if os.path.exists(localB2G):
+                self.device.push(localB2G, self.remoteBinDir)
+                self.device.chmod(self.remoteBinDir, root=True)
+            else:
+                raise Exception("unable to install gre: no APK and not b2g")
 
     def pushLibs(self):
         elfhack = os.path.join(self.localBin, 'elfhack')
         if not os.path.exists(elfhack):
             elfhack = None
         pushed_libs_count = 0
         try:
             dir = tempfile.mkdtemp()
@@ -564,26 +580,16 @@ class PathMapping:
 
 def main():
     if sys.version_info < (2, 7):
         print("Error: You must use python version 2.7 or newer but less than 3.0", file=sys.stderr)
         sys.exit(1)
 
     parser = parser_remote()
     options = parser.parse_args()
-    if not options.localAPK:
-        for file in os.listdir(os.path.join(options.objdir, "dist")):
-            if (file.endswith(".apk") and file.startswith("fennec")):
-                options.localAPK = os.path.join(options.objdir, "dist")
-                options.localAPK = os.path.join(options.localAPK, file)
-                print("using APK: " + options.localAPK, file=sys.stderr)
-                break
-        else:
-            print("Error: please specify an APK", file=sys.stderr)
-            sys.exit(1)
 
     options = verifyRemoteOptions(parser, options)
     log = commandline.setup_logging("Remote XPCShell",
                                     options,
                                     {"tbpl": sys.stdout})
 
     if options['interactive'] and not options['testPath']:
         print("Error: You must specify a test filename in interactive mode!", file=sys.stderr)