--- a/testing/remotecppunittests.py
+++ b/testing/remotecppunittests.py
@@ -1,21 +1,31 @@
#!/usr/bin/env python
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os, sys
+import subprocess
+import tempfile
+from zipfile import ZipFile
import runcppunittests as cppunittests
import mozcrash, mozlog
+import mozfile
import StringIO
import posixpath
from mozdevice import devicemanager, devicemanagerADB, devicemanagerSUT
+try:
+ from mozbuild.base import MozbuildObject
+ build_obj = MozbuildObject.from_environment()
+except ImportError:
+ build_obj = None
+
log = mozlog.getLogger('remotecppunittests')
class RemoteCPPUnitTests(cppunittests.CPPUnitTests):
def __init__(self, devmgr, options, progs):
cppunittests.CPPUnitTests.__init__(self)
self.options = options
self.device = devmgr
self.remote_test_root = self.device.getDeviceRoot() + "/cppunittests"
@@ -37,16 +47,39 @@ class RemoteCPPUnitTests(cppunittests.CP
if self.device.dirExists(self.remote_home_dir):
self.device.removeDir(self.remote_home_dir)
self.device.mkDir(self.remote_home_dir)
self.push_libs()
self.push_progs(progs)
self.device.chmodDir(self.remote_bin_dir)
def push_libs(self):
+ if self.options.local_apk:
+ with mozfile.TemporaryDirectory() as tmpdir:
+ apk_contents = ZipFile(self.options.local_apk)
+ szip = os.path.join(self.options.local_bin, '..', 'host', 'bin', 'szip')
+ if not os.path.exists(szip):
+ # Tinderbox builds must run szip from the test package
+ szip = os.path.join(self.options.local_bin, 'host', 'szip')
+ if not os.path.exists(szip):
+ # If the test package doesn't contain szip, it means files
+ # are not szipped in the test package.
+ szip = None
+
+ for info in apk_contents.infolist():
+ if info.filename.endswith(".so"):
+ print >> sys.stderr, "Pushing %s.." % info.filename
+ remote_file = posixpath.join(self.remote_bin_dir, os.path.basename(info.filename))
+ apk_contents.extract(info, tmpdir)
+ file = os.path.join(tmpdir, info.filename)
+ if szip:
+ out = subprocess.check_output([szip, '-d', file], stderr=subprocess.STDOUT)
+ self.device.pushFile(os.path.join(tmpdir, info.filename), remote_file)
+ return
+
for file in os.listdir(self.options.local_lib):
if file.endswith(".so"):
print >> sys.stderr, "Pushing %s.." % file
remote_file = posixpath.join(self.remote_bin_dir, file)
self.device.pushFile(os.path.join(self.options.local_lib, file), remote_file)
# Additional libraries may be found in a sub-directory such as "lib/armeabi-v7a"
local_arm_lib = os.path.join(self.options.local_lib, "lib")
if os.path.isdir(local_arm_lib):
@@ -136,16 +169,26 @@ class RemoteCPPUnittestOptions(cppunitte
help = "do not copy any files to device (to be used only if device is already setup)")
defaults["setup"] = True
self.add_option("--localLib", action="store",
type = "string", dest = "local_lib",
help = "location of libraries to push -- preferably stripped")
defaults["local_lib"] = None
+ self.add_option("--apk", action="store",
+ type = "string", dest = "local_apk",
+ help = "local path to Fennec APK")
+ defaults["local_apk"] = None
+
+ self.add_option("--localBinDir", action="store",
+ type = "string", dest = "local_bin",
+ help = "local path to bin directory")
+ defaults["local_bin"] = build_obj.bindir if build_obj is not None else None
+
self.add_option("--remoteTestRoot", action = "store",
type = "string", dest = "remote_test_root",
help = "remote directory to use as test root (eg. /data/local/tests)")
# /data/local/tests is used because it is usually not possible to set +x permissions
# on binaries on /mnt/sdcard
defaults["remote_test_root"] = "/data/local/tests"
self.add_option("--addEnv", action = "append",
@@ -156,37 +199,40 @@ class RemoteCPPUnittestOptions(cppunitte
self.set_defaults(**defaults)
def main():
parser = RemoteCPPUnittestOptions()
options, args = parser.parse_args()
if not args:
print >>sys.stderr, """Usage: %s <test binary> [<test binary>...]""" % sys.argv[0]
sys.exit(1)
- if not options.local_lib:
- print >>sys.stderr, """Error: --localLib is required"""
+ if options.local_lib is None and options.local_apk is None:
+ print >>sys.stderr, """Error: --localLib or --apk is required"""
sys.exit(1)
- if not os.path.isdir(options.local_lib):
+ if options.local_lib is not None and not os.path.isdir(options.local_lib):
print >>sys.stderr, """Error: --localLib directory %s not found""" % options.local_lib
sys.exit(1)
+ if options.local_apk is not None and not os.path.isfile(options.local_apk):
+ print >>sys.stderr, """Error: --apk file %s not found""" % options.local_apk
+ sys.exit(1)
if not options.xre_path:
print >>sys.stderr, """Error: --xre-path is required"""
sys.exit(1)
if options.dm_trans == "adb":
if options.device_ip:
dm = devicemanagerADB.DeviceManagerADB(options.device_ip, options.device_port, packageName=None, deviceRoot=options.remote_test_root)
else:
dm = devicemanagerADB.DeviceManagerADB(packageName=None, deviceRoot=options.remote_test_root)
else:
dm = devicemanagerSUT.DeviceManagerSUT(options.device_ip, options.device_port, deviceRoot=options.remote_test_root)
if not options.device_ip:
print "Error: you must provide a device IP to connect to via the --deviceIP option"
sys.exit(1)
options.xre_path = os.path.abspath(options.xre_path)
- progs = [os.path.abspath(p) for p in args]
+ progs = cppunittests.extract_unittests_from_args(args)
tester = RemoteCPPUnitTests(dm, options, progs)
try:
result = tester.run_tests(progs, options.xre_path, options.symbols_path)
except Exception, e:
log.error(str(e))
result = False
sys.exit(0 if result else 1)
--- a/testing/runcppunittests.py
+++ b/testing/runcppunittests.py
@@ -125,32 +125,39 @@ class CPPUnittestOptions(OptionParser):
action = "store", type = "string", dest = "xre_path",
default = None,
help = "absolute path to directory containing XRE (probably xulrunner)")
self.add_option("--symbols-path",
action = "store", type = "string", dest = "symbols_path",
default = None,
help = "absolute path to directory containing breakpad symbols, or the URL of a zip file containing symbols")
+def extract_unittests_from_args(args):
+ """Extract unittests from args, expanding directories as needed"""
+ progs = []
+
+ for p in args:
+ if os.path.isdir(p):
+ #filter out .py files packaged with the unit tests
+ progs.extend([os.path.abspath(os.path.join(p, x)) for x in os.listdir(p) if not x.endswith('.py')])
+ else:
+ progs.append(os.path.abspath(p))
+
+ return progs
+
def main():
parser = CPPUnittestOptions()
options, args = parser.parse_args()
if not args:
print >>sys.stderr, """Usage: %s <test binary> [<test binary>...]""" % sys.argv[0]
sys.exit(1)
if not options.xre_path:
print >>sys.stderr, """Error: --xre-path is required"""
sys.exit(1)
- progs = []
- for p in args:
- if os.path.isdir(p):
- #filter out .py files packaged with the unit tests
- progs.extend([os.path.abspath(os.path.join(p, x)) for x in os.listdir(p) if not x.endswith('.py')])
- else:
- progs.append(os.path.abspath(p))
+ progs = extract_unittests_from_args(args)
options.xre_path = os.path.abspath(options.xre_path)
tester = CPPUnitTests()
try:
result = tester.run_tests(progs, options.xre_path, options.symbols_path)
except Exception, e:
log.error(str(e))
result = False
sys.exit(0 if result else 1)