testing/xpcshell/runtestsb2g.py

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

michael@0 1 #!/usr/bin/env python
michael@0 2 #
michael@0 3 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 6
michael@0 7 import sys
michael@0 8 import os
michael@0 9 sys.path.insert(0, os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0]))))
michael@0 10
michael@0 11 import traceback
michael@0 12 from remotexpcshelltests import RemoteXPCShellTestThread, XPCShellRemote, RemoteXPCShellOptions
michael@0 13 from mozdevice import devicemanagerADB, DMError
michael@0 14
michael@0 15 DEVICE_TEST_ROOT = '/data/local/tests'
michael@0 16
michael@0 17
michael@0 18 from marionette import Marionette
michael@0 19
michael@0 20 class B2GXPCShellTestThread(RemoteXPCShellTestThread):
michael@0 21 # Overridden
michael@0 22 def launchProcess(self, cmd, stdout, stderr, env, cwd):
michael@0 23 try:
michael@0 24 # This returns 1 even when tests pass - hardcode returncode to 0 (bug 773703)
michael@0 25 outputFile = RemoteXPCShellTestThread.launchProcess(self, cmd, stdout, stderr, env, cwd)
michael@0 26 self.shellReturnCode = 0
michael@0 27 except DMError:
michael@0 28 self.shellReturnCode = -1
michael@0 29 outputFile = "xpcshelloutput"
michael@0 30 f = open(outputFile, "a")
michael@0 31 f.write("\n%s" % traceback.format_exc())
michael@0 32 f.close()
michael@0 33 return outputFile
michael@0 34
michael@0 35 class B2GXPCShellRemote(XPCShellRemote):
michael@0 36 # Overridden
michael@0 37 def setLD_LIBRARY_PATH(self):
michael@0 38 self.env['LD_LIBRARY_PATH'] = '/system/b2g'
michael@0 39 if not self.options.use_device_libs:
michael@0 40 # overwrite /system/b2g if necessary
michael@0 41 XPCShellRemote.setLD_LIBRARY_PATH(self)
michael@0 42
michael@0 43 # Overridden
michael@0 44 def setupUtilities(self):
michael@0 45 if self.options.clean:
michael@0 46 # Ensure a fresh directory structure for our tests
michael@0 47 self.clean()
michael@0 48 self.device.mkDir(self.options.remoteTestRoot)
michael@0 49
michael@0 50 XPCShellRemote.setupUtilities(self)
michael@0 51
michael@0 52 def clean(self):
michael@0 53 print >>sys.stderr, "\nCleaning files from previous run.."
michael@0 54 self.device.removeDir(self.options.remoteTestRoot)
michael@0 55
michael@0 56 # Overriden
michael@0 57 def setupTestDir(self):
michael@0 58 if self.device._useZip:
michael@0 59 return XPCShellRemote.setupTestDir(self)
michael@0 60
michael@0 61 for root, dirs, files in os.walk(self.xpcDir):
michael@0 62 for filename in files:
michael@0 63 rel_path = os.path.relpath(os.path.join(root, filename), self.xpcDir)
michael@0 64 test_file = os.path.join(self.remoteScriptsDir, rel_path)
michael@0 65 print 'pushing %s' % test_file
michael@0 66 self.device.pushFile(os.path.join(root, filename), test_file, retryLimit=10)
michael@0 67
michael@0 68 # Overridden
michael@0 69 def pushLibs(self):
michael@0 70 if not self.options.use_device_libs:
michael@0 71 count = XPCShellRemote.pushLibs(self)
michael@0 72 if not count:
michael@0 73 # couldn't find any libs, fallback to device libs
michael@0 74 self.env['LD_LIBRARY_PATH'] = '/system/b2g'
michael@0 75 self.options.use_device_libs = True
michael@0 76
michael@0 77 class B2GOptions(RemoteXPCShellOptions):
michael@0 78
michael@0 79 def __init__(self):
michael@0 80 RemoteXPCShellOptions.__init__(self)
michael@0 81 defaults = {}
michael@0 82
michael@0 83 self.add_option('--b2gpath', action='store',
michael@0 84 type='string', dest='b2g_path',
michael@0 85 help="Path to B2G repo or qemu dir")
michael@0 86 defaults['b2g_path'] = None
michael@0 87
michael@0 88 self.add_option('--emupath', action='store',
michael@0 89 type='string', dest='emu_path',
michael@0 90 help="Path to emulator folder (if different "
michael@0 91 "from b2gpath")
michael@0 92
michael@0 93 self.add_option('--no-clean', action='store_false',
michael@0 94 dest='clean',
michael@0 95 help="Do not clean TESTROOT. Saves [lots of] time")
michael@0 96 defaults['clean'] = True
michael@0 97
michael@0 98 defaults['emu_path'] = None
michael@0 99
michael@0 100 self.add_option('--emulator', action='store',
michael@0 101 type='string', dest='emulator',
michael@0 102 help="Architecture of emulator to use: x86 or arm")
michael@0 103 defaults['emulator'] = None
michael@0 104
michael@0 105 self.add_option('--no-window', action='store_true',
michael@0 106 dest='no_window',
michael@0 107 help="Pass --no-window to the emulator")
michael@0 108 defaults['no_window'] = False
michael@0 109
michael@0 110 self.add_option('--adbpath', action='store',
michael@0 111 type='string', dest='adb_path',
michael@0 112 help="Path to adb")
michael@0 113 defaults['adb_path'] = 'adb'
michael@0 114
michael@0 115 self.add_option('--address', action='store',
michael@0 116 type='string', dest='address',
michael@0 117 help="host:port of running Gecko instance to connect to")
michael@0 118 defaults['address'] = None
michael@0 119
michael@0 120 self.add_option('--use-device-libs', action='store_true',
michael@0 121 dest='use_device_libs',
michael@0 122 help="Don't push .so's")
michael@0 123 defaults['use_device_libs'] = False
michael@0 124 self.add_option("--gecko-path", action="store",
michael@0 125 type="string", dest="geckoPath",
michael@0 126 help="the path to a gecko distribution that should "
michael@0 127 "be installed on the emulator prior to test")
michael@0 128 defaults["geckoPath"] = None
michael@0 129 self.add_option("--logcat-dir", action="store",
michael@0 130 type="string", dest="logcat_dir",
michael@0 131 help="directory to store logcat dump files")
michael@0 132 defaults["logcat_dir"] = None
michael@0 133 self.add_option('--busybox', action='store',
michael@0 134 type='string', dest='busybox',
michael@0 135 help="Path to busybox binary to install on device")
michael@0 136 defaults['busybox'] = None
michael@0 137
michael@0 138 defaults["remoteTestRoot"] = DEVICE_TEST_ROOT
michael@0 139 defaults['dm_trans'] = 'adb'
michael@0 140 defaults['debugger'] = None
michael@0 141 defaults['debuggerArgs'] = None
michael@0 142
michael@0 143 self.set_defaults(**defaults)
michael@0 144
michael@0 145 def verifyRemoteOptions(self, options):
michael@0 146 if options.b2g_path is None:
michael@0 147 self.error("Need to specify a --b2gpath")
michael@0 148
michael@0 149 if options.geckoPath and not options.emulator:
michael@0 150 self.error("You must specify --emulator if you specify --gecko-path")
michael@0 151
michael@0 152 if options.logcat_dir and not options.emulator:
michael@0 153 self.error("You must specify --emulator if you specify --logcat-dir")
michael@0 154 return RemoteXPCShellOptions.verifyRemoteOptions(self, options)
michael@0 155
michael@0 156 def run_remote_xpcshell(parser, options, args):
michael@0 157 options = parser.verifyRemoteOptions(options)
michael@0 158
michael@0 159 # Create the Marionette instance
michael@0 160 kwargs = {}
michael@0 161 if options.emulator:
michael@0 162 kwargs['emulator'] = options.emulator
michael@0 163 if options.no_window:
michael@0 164 kwargs['noWindow'] = True
michael@0 165 if options.geckoPath:
michael@0 166 kwargs['gecko_path'] = options.geckoPath
michael@0 167 if options.logcat_dir:
michael@0 168 kwargs['logcat_dir'] = options.logcat_dir
michael@0 169 if options.busybox:
michael@0 170 kwargs['busybox'] = options.busybox
michael@0 171 if options.symbolsPath:
michael@0 172 kwargs['symbols_path'] = options.symbolsPath
michael@0 173 if options.b2g_path:
michael@0 174 kwargs['homedir'] = options.emu_path or options.b2g_path
michael@0 175 if options.address:
michael@0 176 host, port = options.address.split(':')
michael@0 177 kwargs['host'] = host
michael@0 178 kwargs['port'] = int(port)
michael@0 179 kwargs['baseurl'] = 'http://%s:%d/' % (host, int(port))
michael@0 180 if options.emulator:
michael@0 181 kwargs['connectToRunningEmulator'] = True
michael@0 182 marionette = Marionette(**kwargs)
michael@0 183
michael@0 184 if options.emulator:
michael@0 185 dm = marionette.emulator.dm
michael@0 186 else:
michael@0 187 # Create the DeviceManager instance
michael@0 188 kwargs = {'adbPath': options.adb_path}
michael@0 189 if options.deviceIP:
michael@0 190 kwargs['host'] = options.deviceIP
michael@0 191 kwargs['port'] = options.devicePort
michael@0 192 kwargs['deviceRoot'] = options.remoteTestRoot
michael@0 193 dm = devicemanagerADB.DeviceManagerADB(**kwargs)
michael@0 194
michael@0 195 if not options.remoteTestRoot:
michael@0 196 options.remoteTestRoot = dm.getDeviceRoot()
michael@0 197 xpcsh = B2GXPCShellRemote(dm, options, args)
michael@0 198
michael@0 199 # we don't run concurrent tests on mobile
michael@0 200 options.sequential = True
michael@0 201
michael@0 202 try:
michael@0 203 if not xpcsh.runTests(xpcshell='xpcshell', testdirs=args[0:],
michael@0 204 testClass=B2GXPCShellTestThread,
michael@0 205 mobileArgs=xpcsh.mobileArgs,
michael@0 206 **options.__dict__):
michael@0 207 sys.exit(1)
michael@0 208 except:
michael@0 209 print "Automation Error: Exception caught while running tests"
michael@0 210 traceback.print_exc()
michael@0 211 sys.exit(1)
michael@0 212
michael@0 213 def main():
michael@0 214 parser = B2GOptions()
michael@0 215 options, args = parser.parse_args()
michael@0 216
michael@0 217 run_remote_xpcshell(parser, options, args)
michael@0 218
michael@0 219 # You usually run this like :
michael@0 220 # python runtestsb2g.py --emulator arm --b2gpath $B2GPATH --manifest $MANIFEST [--xre-path $MOZ_HOST_BIN
michael@0 221 # --adbpath $ADB_PATH
michael@0 222 # ...]
michael@0 223 #
michael@0 224 # For xUnit output you should also pass in --tests-root-dir ..objdir-gecko/_tests
michael@0 225 # --xunit-file ..objdir_gecko/_tests/results.xml
michael@0 226 # --xunit-suite-name xpcshell-tests
michael@0 227 if __name__ == '__main__':
michael@0 228 main()

mercurial