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/.
9 sys
.path
.insert(0, os
.path
.abspath(os
.path
.realpath(os
.path
.dirname(sys
.argv
[0]))))
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
):
22 def launchProcess(self
, cmd
, stdout
, stderr
, env
, cwd
, timeout
=None):
24 # This returns 1 even when tests pass - hardcode returncode to 0 (bug 773703)
25 outputFile
= RemoteXPCShellTestThread
.launchProcess(self
, cmd
, stdout
, stderr
, env
, cwd
, timeout
=timeout
)
26 self
.shellReturnCode
= 0
28 self
.shellReturnCode
= -1
29 outputFile
= "xpcshelloutput"
30 f
= open(outputFile
, "a")
31 f
.write("\n%s" % traceback
.format_exc())
35 class B2GXPCShellRemote(XPCShellRemote
):
37 def setLD_LIBRARY_PATH(self
):
38 self
.env
['LD_LIBRARY_PATH'] = '/system/b2g'
39 if not self
.options
.use_device_libs
:
40 # overwrite /system/b2g if necessary
41 XPCShellRemote
.setLD_LIBRARY_PATH(self
)
44 def setupUtilities(self
):
45 if self
.options
.clean
:
46 # Ensure a fresh directory structure for our tests
48 self
.device
.mkDir(self
.options
.remoteTestRoot
)
50 XPCShellRemote
.setupUtilities(self
)
53 print >>sys
.stderr
, "\nCleaning files from previous run.."
54 self
.device
.removeDir(self
.options
.remoteTestRoot
)
57 def setupTestDir(self
):
58 if self
.device
._useZip
:
59 return XPCShellRemote
.setupTestDir(self
)
61 for root
, dirs
, files
in os
.walk(self
.xpcDir
):
62 for filename
in files
:
63 rel_path
= os
.path
.relpath(os
.path
.join(root
, filename
), self
.xpcDir
)
64 test_file
= os
.path
.join(self
.remoteScriptsDir
, rel_path
)
65 print 'pushing %s' % test_file
66 self
.device
.pushFile(os
.path
.join(root
, filename
), test_file
, retryLimit
=10)
70 if not self
.options
.use_device_libs
:
71 count
= XPCShellRemote
.pushLibs(self
)
73 # couldn't find any libs, fallback to device libs
74 self
.env
['LD_LIBRARY_PATH'] = '/system/b2g'
75 self
.options
.use_device_libs
= True
77 class B2GOptions(RemoteXPCShellOptions
):
80 RemoteXPCShellOptions
.__init
__(self
)
83 self
.add_option('--b2gpath', action
='store',
84 type='string', dest
='b2g_path',
85 help="Path to B2G repo or qemu dir")
86 defaults
['b2g_path'] = None
88 self
.add_option('--emupath', action
='store',
89 type='string', dest
='emu_path',
90 help="Path to emulator folder (if different "
93 self
.add_option('--no-clean', action
='store_false',
95 help="Do not clean TESTROOT. Saves [lots of] time")
96 defaults
['clean'] = True
98 defaults
['emu_path'] = None
100 self
.add_option('--emulator', action
='store',
101 type='string', dest
='emulator',
102 help="Architecture of emulator to use: x86 or arm")
103 defaults
['emulator'] = None
105 self
.add_option('--no-window', action
='store_true',
107 help="Pass --no-window to the emulator")
108 defaults
['no_window'] = False
110 self
.add_option('--adbpath', action
='store',
111 type='string', dest
='adb_path',
113 defaults
['adb_path'] = 'adb'
115 self
.add_option('--address', action
='store',
116 type='string', dest
='address',
117 help="host:port of running Gecko instance to connect to")
118 defaults
['address'] = None
120 self
.add_option('--use-device-libs', action
='store_true',
121 dest
='use_device_libs',
122 help="Don't push .so's")
123 defaults
['use_device_libs'] = False
124 self
.add_option("--gecko-path", action
="store",
125 type="string", dest
="geckoPath",
126 help="the path to a gecko distribution that should "
127 "be installed on the emulator prior to test")
128 defaults
["geckoPath"] = None
129 self
.add_option("--logdir", action
="store",
130 type="string", dest
="logdir",
131 help="directory to store log files")
132 defaults
["logdir"] = None
133 self
.add_option('--busybox', action
='store',
134 type='string', dest
='busybox',
135 help="Path to busybox binary to install on device")
136 defaults
['busybox'] = None
138 defaults
["remoteTestRoot"] = DEVICE_TEST_ROOT
139 defaults
['dm_trans'] = 'adb'
140 defaults
['debugger'] = None
141 defaults
['debuggerArgs'] = None
143 self
.set_defaults(**defaults
)
145 def verifyRemoteOptions(self
, options
):
146 if options
.b2g_path
is None:
147 self
.error("Need to specify a --b2gpath")
149 if options
.geckoPath
and not options
.emulator
:
150 self
.error("You must specify --emulator if you specify --gecko-path")
152 if options
.logdir
and not options
.emulator
:
153 self
.error("You must specify --emulator if you specify --logdir")
154 return RemoteXPCShellOptions
.verifyRemoteOptions(self
, options
)
156 def run_remote_xpcshell(parser
, options
, args
):
157 options
= parser
.verifyRemoteOptions(options
)
159 # Create the Marionette instance
162 kwargs
['emulator'] = options
.emulator
163 if options
.no_window
:
164 kwargs
['noWindow'] = True
165 if options
.geckoPath
:
166 kwargs
['gecko_path'] = options
.geckoPath
168 kwargs
['logdir'] = options
.logdir
170 kwargs
['busybox'] = options
.busybox
171 if options
.symbolsPath
:
172 kwargs
['symbols_path'] = options
.symbolsPath
174 kwargs
['homedir'] = options
.emu_path
or options
.b2g_path
176 host
, port
= options
.address
.split(':')
177 kwargs
['host'] = host
178 kwargs
['port'] = int(port
)
179 kwargs
['baseurl'] = 'http://%s:%d/' % (host
, int(port
))
181 kwargs
['connectToRunningEmulator'] = True
182 marionette
= Marionette(**kwargs
)
185 dm
= marionette
.emulator
.dm
187 # Create the DeviceManager instance
188 kwargs
= {'adbPath': options
.adb_path
}
190 kwargs
['host'] = options
.deviceIP
191 kwargs
['port'] = options
.devicePort
192 kwargs
['deviceRoot'] = options
.remoteTestRoot
193 dm
= devicemanagerADB
.DeviceManagerADB(**kwargs
)
195 if not options
.remoteTestRoot
:
196 options
.remoteTestRoot
= dm
.deviceRoot
197 xpcsh
= B2GXPCShellRemote(dm
, options
, args
)
199 # we don't run concurrent tests on mobile
200 options
.sequential
= True
203 if not xpcsh
.runTests(xpcshell
='xpcshell', testdirs
=args
[0:],
204 testClass
=B2GXPCShellTestThread
,
205 mobileArgs
=xpcsh
.mobileArgs
,
209 print "Automation Error: Exception caught while running tests"
210 traceback
.print_exc()
214 parser
= B2GOptions()
215 options
, args
= parser
.parse_args()
217 run_remote_xpcshell(parser
, options
, args
)
219 # You usually run this like :
220 # python runtestsb2g.py --emulator arm --b2gpath $B2GPATH --manifest $MANIFEST [--xre-path $MOZ_HOST_BIN
221 # --adbpath $ADB_PATH
224 # For xUnit output you should also pass in --tests-root-dir ..objdir-gecko/_tests
225 # --xunit-file ..objdir_gecko/_tests/results.xml
226 # --xunit-suite-name xpcshell-tests
227 if __name__
== '__main__':