testing/xpcshell/runtestsb2g.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/testing/xpcshell/runtestsb2g.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,228 @@
     1.4 +#!/usr/bin/env python
     1.5 +#
     1.6 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.7 +# License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 +# file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.9 +
    1.10 +import sys
    1.11 +import os
    1.12 +sys.path.insert(0, os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0]))))
    1.13 +
    1.14 +import traceback
    1.15 +from remotexpcshelltests import RemoteXPCShellTestThread, XPCShellRemote, RemoteXPCShellOptions
    1.16 +from mozdevice import devicemanagerADB, DMError
    1.17 +
    1.18 +DEVICE_TEST_ROOT = '/data/local/tests'
    1.19 +
    1.20 +
    1.21 +from marionette import Marionette
    1.22 +
    1.23 +class B2GXPCShellTestThread(RemoteXPCShellTestThread):
    1.24 +    # Overridden
    1.25 +    def launchProcess(self, cmd, stdout, stderr, env, cwd):
    1.26 +        try:
    1.27 +            # This returns 1 even when tests pass - hardcode returncode to 0 (bug 773703)
    1.28 +            outputFile = RemoteXPCShellTestThread.launchProcess(self, cmd, stdout, stderr, env, cwd)
    1.29 +            self.shellReturnCode = 0
    1.30 +        except DMError:
    1.31 +            self.shellReturnCode = -1
    1.32 +            outputFile = "xpcshelloutput"
    1.33 +            f = open(outputFile, "a")
    1.34 +            f.write("\n%s" % traceback.format_exc())
    1.35 +            f.close()
    1.36 +        return outputFile
    1.37 +
    1.38 +class B2GXPCShellRemote(XPCShellRemote):
    1.39 +    # Overridden
    1.40 +    def setLD_LIBRARY_PATH(self):
    1.41 +        self.env['LD_LIBRARY_PATH'] = '/system/b2g'
    1.42 +        if not self.options.use_device_libs:
    1.43 +            # overwrite /system/b2g if necessary
    1.44 +            XPCShellRemote.setLD_LIBRARY_PATH(self)
    1.45 +
    1.46 +    # Overridden
    1.47 +    def setupUtilities(self):
    1.48 +        if self.options.clean:
    1.49 +            # Ensure a fresh directory structure for our tests
    1.50 +            self.clean()
    1.51 +            self.device.mkDir(self.options.remoteTestRoot)
    1.52 +
    1.53 +        XPCShellRemote.setupUtilities(self)
    1.54 +
    1.55 +    def clean(self):
    1.56 +        print >>sys.stderr, "\nCleaning files from previous run.."
    1.57 +        self.device.removeDir(self.options.remoteTestRoot)
    1.58 +
    1.59 +    # Overriden
    1.60 +    def setupTestDir(self):
    1.61 +        if self.device._useZip:
    1.62 +            return XPCShellRemote.setupTestDir(self)
    1.63 +
    1.64 +        for root, dirs, files in os.walk(self.xpcDir):
    1.65 +            for filename in files:
    1.66 +                rel_path = os.path.relpath(os.path.join(root, filename), self.xpcDir)
    1.67 +                test_file = os.path.join(self.remoteScriptsDir, rel_path)
    1.68 +                print 'pushing %s' % test_file
    1.69 +                self.device.pushFile(os.path.join(root, filename), test_file, retryLimit=10)
    1.70 +
    1.71 +    # Overridden
    1.72 +    def pushLibs(self):
    1.73 +        if not self.options.use_device_libs:
    1.74 +            count = XPCShellRemote.pushLibs(self)
    1.75 +            if not count:
    1.76 +                # couldn't find any libs, fallback to device libs
    1.77 +                self.env['LD_LIBRARY_PATH'] = '/system/b2g'
    1.78 +                self.options.use_device_libs = True
    1.79 +
    1.80 +class B2GOptions(RemoteXPCShellOptions):
    1.81 +
    1.82 +    def __init__(self):
    1.83 +        RemoteXPCShellOptions.__init__(self)
    1.84 +        defaults = {}
    1.85 +
    1.86 +        self.add_option('--b2gpath', action='store',
    1.87 +                        type='string', dest='b2g_path',
    1.88 +                        help="Path to B2G repo or qemu dir")
    1.89 +        defaults['b2g_path'] = None
    1.90 +
    1.91 +        self.add_option('--emupath', action='store',
    1.92 +                        type='string', dest='emu_path',
    1.93 +                        help="Path to emulator folder (if different "
    1.94 +                                                      "from b2gpath")
    1.95 +
    1.96 +        self.add_option('--no-clean', action='store_false',
    1.97 +                        dest='clean',
    1.98 +                        help="Do not clean TESTROOT. Saves [lots of] time")
    1.99 +        defaults['clean'] = True
   1.100 +
   1.101 +        defaults['emu_path'] = None
   1.102 +
   1.103 +        self.add_option('--emulator', action='store',
   1.104 +                        type='string', dest='emulator',
   1.105 +                        help="Architecture of emulator to use: x86 or arm")
   1.106 +        defaults['emulator'] = None
   1.107 +
   1.108 +        self.add_option('--no-window', action='store_true',
   1.109 +                        dest='no_window',
   1.110 +                        help="Pass --no-window to the emulator")
   1.111 +        defaults['no_window'] = False
   1.112 +
   1.113 +        self.add_option('--adbpath', action='store',
   1.114 +                        type='string', dest='adb_path',
   1.115 +                        help="Path to adb")
   1.116 +        defaults['adb_path'] = 'adb'
   1.117 +
   1.118 +        self.add_option('--address', action='store',
   1.119 +                        type='string', dest='address',
   1.120 +                        help="host:port of running Gecko instance to connect to")
   1.121 +        defaults['address'] = None
   1.122 +
   1.123 +        self.add_option('--use-device-libs', action='store_true',
   1.124 +                        dest='use_device_libs',
   1.125 +                        help="Don't push .so's")
   1.126 +        defaults['use_device_libs'] = False
   1.127 +        self.add_option("--gecko-path", action="store",
   1.128 +                        type="string", dest="geckoPath",
   1.129 +                        help="the path to a gecko distribution that should "
   1.130 +                        "be installed on the emulator prior to test")
   1.131 +        defaults["geckoPath"] = None
   1.132 +        self.add_option("--logcat-dir", action="store",
   1.133 +                        type="string", dest="logcat_dir",
   1.134 +                        help="directory to store logcat dump files")
   1.135 +        defaults["logcat_dir"] = None
   1.136 +        self.add_option('--busybox', action='store',
   1.137 +                        type='string', dest='busybox',
   1.138 +                        help="Path to busybox binary to install on device")
   1.139 +        defaults['busybox'] = None
   1.140 +
   1.141 +        defaults["remoteTestRoot"] = DEVICE_TEST_ROOT
   1.142 +        defaults['dm_trans'] = 'adb'
   1.143 +        defaults['debugger'] = None
   1.144 +        defaults['debuggerArgs'] = None
   1.145 +
   1.146 +        self.set_defaults(**defaults)
   1.147 +
   1.148 +    def verifyRemoteOptions(self, options):
   1.149 +        if options.b2g_path is None:
   1.150 +            self.error("Need to specify a --b2gpath")
   1.151 +
   1.152 +        if options.geckoPath and not options.emulator:
   1.153 +            self.error("You must specify --emulator if you specify --gecko-path")
   1.154 +
   1.155 +        if options.logcat_dir and not options.emulator:
   1.156 +            self.error("You must specify --emulator if you specify --logcat-dir")
   1.157 +        return RemoteXPCShellOptions.verifyRemoteOptions(self, options)
   1.158 +
   1.159 +def run_remote_xpcshell(parser, options, args):
   1.160 +    options = parser.verifyRemoteOptions(options)
   1.161 +
   1.162 +    # Create the Marionette instance
   1.163 +    kwargs = {}
   1.164 +    if options.emulator:
   1.165 +        kwargs['emulator'] = options.emulator
   1.166 +        if options.no_window:
   1.167 +            kwargs['noWindow'] = True
   1.168 +        if options.geckoPath:
   1.169 +            kwargs['gecko_path'] = options.geckoPath
   1.170 +        if options.logcat_dir:
   1.171 +            kwargs['logcat_dir'] = options.logcat_dir
   1.172 +        if options.busybox:
   1.173 +            kwargs['busybox'] = options.busybox
   1.174 +        if options.symbolsPath:
   1.175 +            kwargs['symbols_path'] = options.symbolsPath
   1.176 +    if options.b2g_path:
   1.177 +        kwargs['homedir'] = options.emu_path or options.b2g_path
   1.178 +    if options.address:
   1.179 +        host, port = options.address.split(':')
   1.180 +        kwargs['host'] = host
   1.181 +        kwargs['port'] = int(port)
   1.182 +        kwargs['baseurl'] = 'http://%s:%d/' % (host, int(port))
   1.183 +        if options.emulator:
   1.184 +            kwargs['connectToRunningEmulator'] = True
   1.185 +    marionette = Marionette(**kwargs)
   1.186 +
   1.187 +    if options.emulator:
   1.188 +        dm = marionette.emulator.dm
   1.189 +    else:
   1.190 +        # Create the DeviceManager instance
   1.191 +        kwargs = {'adbPath': options.adb_path}
   1.192 +        if options.deviceIP:
   1.193 +            kwargs['host'] = options.deviceIP
   1.194 +            kwargs['port'] = options.devicePort
   1.195 +        kwargs['deviceRoot'] = options.remoteTestRoot
   1.196 +        dm = devicemanagerADB.DeviceManagerADB(**kwargs)
   1.197 +
   1.198 +    if not options.remoteTestRoot:
   1.199 +        options.remoteTestRoot = dm.getDeviceRoot()
   1.200 +    xpcsh = B2GXPCShellRemote(dm, options, args)
   1.201 +
   1.202 +    # we don't run concurrent tests on mobile
   1.203 +    options.sequential = True
   1.204 +
   1.205 +    try:
   1.206 +        if not xpcsh.runTests(xpcshell='xpcshell', testdirs=args[0:],
   1.207 +                                 testClass=B2GXPCShellTestThread,
   1.208 +                                 mobileArgs=xpcsh.mobileArgs,
   1.209 +                                 **options.__dict__):
   1.210 +            sys.exit(1)
   1.211 +    except:
   1.212 +        print "Automation Error: Exception caught while running tests"
   1.213 +        traceback.print_exc()
   1.214 +        sys.exit(1)
   1.215 +
   1.216 +def main():
   1.217 +    parser = B2GOptions()
   1.218 +    options, args = parser.parse_args()
   1.219 +
   1.220 +    run_remote_xpcshell(parser, options, args)
   1.221 +
   1.222 +# You usually run this like :
   1.223 +# python runtestsb2g.py --emulator arm --b2gpath $B2GPATH --manifest $MANIFEST [--xre-path $MOZ_HOST_BIN
   1.224 +#                                                                               --adbpath $ADB_PATH
   1.225 +#                                                                               ...]
   1.226 +#
   1.227 +# For xUnit output you should also pass in --tests-root-dir ..objdir-gecko/_tests
   1.228 +#                                          --xunit-file ..objdir_gecko/_tests/results.xml
   1.229 +#                                          --xunit-suite-name xpcshell-tests
   1.230 +if __name__ == '__main__':
   1.231 +    main()

mercurial