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