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 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'
27 XPCShellRemote
.setLD_LIBRARY_PATH(self
, env
)
30 def launchProcess(self
, cmd
, stdout
, stderr
, env
, cwd
):
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
36 self
.shellReturnCode
= -1
37 outputFile
= "xpcshelloutput"
38 f
= open(outputFile
, "a")
39 f
.write("\n%s" % traceback
.format_exc())
43 class B2GXPCShellRemote(XPCShellRemote
):
45 def setupUtilities(self
):
46 if self
.options
.clean
:
47 # Ensure a fresh directory structure for our tests
49 self
.device
.mkDir(self
.options
.remoteTestRoot
)
51 XPCShellRemote
.setupUtilities(self
)
54 print >>sys
.stderr
, "\nCleaning files from previous run.."
55 self
.device
.removeDir(self
.options
.remoteTestRoot
)
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)
71 if not self
.options
.use_device_libs
:
72 XPCShellRemote
.pushLibs(self
)
74 class B2GOptions(RemoteXPCShellOptions
):
77 RemoteXPCShellOptions
.__init
__(self
)
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 "
90 self
.add_option('--no-clean', action
='store_false',
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',
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',
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
)
154 parser
= B2GOptions()
155 options
, args
= parser
.parse_args()
156 options
= parser
.verifyRemoteOptions(options
)
158 # Create the Marionette instance
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
169 kwargs
['busybox'] = options
.busybox
170 if options
.symbolsPath
:
171 kwargs
['symbols_path'] = options
.symbolsPath
173 kwargs
['homedir'] = options
.emu_path
or options
.b2g_path
175 host
, port
= options
.address
.split(':')
176 kwargs
['host'] = host
177 kwargs
['port'] = int(port
)
178 kwargs
['baseurl'] = 'http://%s:%d/' % (host
, int(port
))
180 kwargs
['connectToRunningEmulator'] = True
181 marionette
= Marionette(**kwargs
)
183 # Create the DeviceManager instance
184 kwargs
= {'adbPath': options
.adb_path
}
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
199 if not xpcsh
.runTests(xpcshell
='xpcshell', testdirs
=args
[0:],
200 testClass
=B2GXPCShellTestThread
,
201 mobileArgs
=xpcsh
.mobileArgs
,
205 print "Automation Error: Exception caught while running tests"
206 traceback
.print_exc()
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
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__':