Files
palemoon27/testing/remotecppunittests.py
T
roytam1 c1eaf73bd6 import changes from `dev' branch of rmottola/Arctic-Fox:
- bug 1162519 - use winrm for mach clobber on Windows. r=gps (707dfeb728)
- No bug: Make ./mach clobber work on windows without winrm.exe. r=me (bb55cb7a1d)
- Bug 1176642 - Import proper mozinfo package; r=me (f5baa80864)
- Bug 1216171 - Fix MozbuildObject.bindir to import the correct mozinfo, r=jmaher (58df60341e)
- Bug 1216575 - [mozbuild] Remove if statement that sets bindir to resource dir on osx, r=spohl (079d7483c8)
- Bug 1190474 - Allow test-specific timeouts to be specified in cppunittest.ini, r=chmanchester (86d5ffa97c)
- Bug 1181867 - move -runtime flag to runtests.py so it gets set in automation; r=jland,ahalberstadt (939efb386c)
- Bug 1185761 - [mochitest] Allow boolean values to --keep-open for overriding the default, r=ted (b7d1c99778)
- Bug 1156425 - Allow Android test jobs to run for up to 75 minutes; r=ryanvm (9930c4f8e9)
- Bug 1171303 - Set pref extensions.autoupdate.enabled to false to avoid testOfflinePage failures; r=mfinkle (400ed217a5)
- Bug 1179981 - A new test harness for robocop; r=jmaher (9c6b066733)
- Bug 999450 - Add find-test-chunk command in mach to discover the chunk for a mochitest on a platform. r=chmanchester (b9e5b64fc6)
- Bug 1140441 - Add substring matching option to |mach mach-debug-commands|, r=gps (4ad5b5362e)
- Bug 1090276 - Support mach cppunittest on Android; r=dminor (a5dc185c03)
- Bug 1181261 - Merge configs from testing/config/mozharness into mozharness proper, r=chmanchester (9d2a45b3de)
- Bug 1217144: Allow for cppunittest to be run locally on OSX. r=erahm (f470637d77)
- Bug 1205144 - Remove 'REMOVED' commands from output of mach-commands and mach-debug-commands. r=gps DONTBUILD (19a8e3b0bf)
- Bug 1203627 - Change search order for finding android emulator; r=ahal (ca1b0eb350)
- Bug 1199377 - Fetch host-utils for Android tests when needed; r=jmaher (c276a035af)
- Bug 1211407 - Make |mach mochitest| use the adb under `out/host/*/bin` if no --adbpath specified. r=ahal (e8acae4e41)
- Bug 1122590 - Make |mach mochitest| properly detect devtools tests (and other subsuites), r=chmanchester, DONTBUILD, a=NPOTB (5034e6aac6)
- Bug 938994 - Move build/mobile/robocop into mobile/android/tests/browser/robocop. r=gbrown (f386204b05)
- Bug 1208002: Optimize creation of RegExpMatch result for 'str.match', r=bhackett (b8dccae77a)
- Bug 1214548 - GenerateLcovInfo: Check that getOrCreateScript does not OOM. r=bhackett (9bbd59a94e)
- Bug 1155937 - Fix comment in IonBuilder::getPropTryInnerize. r=bz (a8a05ec18f)
- Bug 1213146 - IonMonkey: MIPS: Modify the last two args of Assembler::bind to generic type. r=arai (54123a5c20)
- Bug 1220505 - IonMonkey: MIPS64: Fix workaround for Loongson3 in Assembler::bind. r=huangwenjun06 (fff27fcfeb)
- Bug 1220939 - IonMonkey: MIPS: Check oom() before using editSrc() and Label::use(). r=jolesen (a2a25baf45)
- Bug 1205167 - IonMonkey: MIPS64: Fix typo in Assembler-mips64. r=nbp (b339f0475b)
- Bug 1217873 - IonMonkey: MIPS: Move BailoutStack to architecture dependent. r=arai f=nbp (cd6a703e71)
- Bug 1217873 - IonMonkey: MIPS: Move visitOutOfLineBailout to architecture dependent. r=arai f=nbp (4fc456d837)
- Bug 1217873 - IonMonkey: MIPS64: Simplify BailoutStack for MIPS64. r=lth (baafdfefeb)
- Bug 1090957 - IonMonkey: MIPS64: Implement atomics in MacroAssembler. r=lth (64df89560f)
- Bug 1219157 - IonMonkey: MIPS64: Delete CodeOffsetLabel::fixup(). r=jolesen (20a4bb8de4)
- Bug 1219125 - IonMonkey: MIPS64: Fix profiler/test-bug1026485.js failure in debug mode. r=arai (701dca2337)
- Bug 1213532 - IonMonkey: MIPS32: Fix call FloatRegistersMIPSShared::GetName recursive. r=arai (96cb12e849)
- Bug 1213532 - IonMonkey: MIPS32: Rename BaseFloatRegisters to FloatRegistersMIPSShared. r=arai (d0bbaaad17)
- Bug 1066642 - IonMonkey: MIPS32: Do not allocate odd FP registers on Loongson CPU-s. r=arai (fe0e2e6f0a)
- Bug 1215420 - IonMonkey: MIPS32: Fix FloatRegister::encoding. r=nbp (03534b7eb6)
- Bug 1129813 - special-case "while" and "for" line notes; r=jimb (000e7e8bea)
- Bug 1139235 - don't set line for literal case expressions; r=fitzgen (b317b4c427)
- Bug 1220766 - Don't assume ListIterator's next slot contains an int32 r=shu (65b563b78b)
- Bug 1224222 - Guard against setters on Array.prototype in self-hosted Module code. r=jonco (5ac5b48c5b)
- Bug 1219044 - Take account of the fact that module import bindings may be null if we have hit OOM r=terrence (27b1e057ad)
- Bug 1219408 - Throw error if module loader attempts to evaluate an uninstantiated module r=shu (b89af38208)
- clean up double definition (92c2e6c4d2)
- remove, since 1170372 has long since landed and no trace can be found in FF/TFF (e417a4dc58)
- Bug 1215430 - Inline the guts of the shared method implementing |new RegExp(...)| and |RegExp.prototype.compile| into each separate method, for clarity. r=efaust (5be0d360f2)
- Bug 1215430 - Refactor RegExp code to be more spec-like in its ordering of things, and eliminate the confusing statefulness of RegExpObjectBuilder. r=efaust (fe24ae119d)
- Bug 1209001 - Add test code for OOM handling in parseModule() r=terrence (c36cc5e5c1)
- Bug 978802 - Crash in argumentsOptimizationFailed() if we run out of memory r=jandem (de1bb00bd7)
- Bug 1212128 - Annotate oomInGetJumpLabelForBranch with allow-oom. (rs=terrence) (72304c3b03)
- Bug 1212469 - Make oomTest() into a shell function r=nbp (6c19395033)
- various cleanups (d12627b23f)
- Bug 1216260 - Replace mozMatchesSelector with matches in add-on SDK. r=matteo (7457c563b6)
- Bug 1216269 - Fix tab-firefox.js typo in tab attach method. r=zer0 (a59f126ec8)
- var-let (d81c53a0ce)
- Bug 1139100 - Apply proper checking for command existence; r=ahal (5d0f1fc75d)
- Bug 1176620 - Refactor how mach command metadata is stored; r=ahal (aa6dc7c786)
- Bug 1176620 - Pass fewer arguments into MethodHandler; r=ahal (fa64eef7ab)
- Bug 1176620 - Eliminate MethodHandler; r=ahal (04130c8e62)
- Bug 1177476 - Fix require_conditions regression in mach, r=gps (30c6400900)
- Bug 1208320 - Allow FileFinder to find dot files; r=glandium (639f2695a0)
- Bug 1210329 - Remove support for line endings munging in the preprocessor. r=gps (cbb01fa96e)
- Bug 1211957 - Add the repackage step at the end of a faster build on Mac. r=gps (48fb11101a)
- Bug 1210687 - Use install manifests for jar.mn files in FasterMake backend. r=gps (cb0b4e2c92)
- Bug 1215238 - Mention the included filepath in pre-processed js sources with #includes. r=glandium (3b3590e287)
- Bug 1209839 - Remove the -E option to the preprocessor. r=gps (63c60f15cd)
- Bug 1215526 - part 3 - make preprocessor.preprocessor report all included files; r=glandium (c4949756ff)
- bit of Bug 1207708 - Part 2 (2a87bac13f)
- some var fixes (35b7ffd9bd)
2022-12-22 10:41:52 +08:00

283 lines
12 KiB
Python

#!/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
import mozfile
import mozinfo
import mozlog
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
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.deviceRoot + "/cppunittests"
self.remote_bin_dir = posixpath.join(self.remote_test_root, "b")
self.remote_tmp_dir = posixpath.join(self.remote_test_root, "tmp")
self.remote_home_dir = posixpath.join(self.remote_test_root, "h")
if options.setup:
self.setup_bin(progs)
def setup_bin(self, progs):
if not self.device.dirExists(self.remote_test_root):
self.device.mkDir(self.remote_test_root)
if self.device.dirExists(self.remote_tmp_dir):
self.device.removeDir(self.remote_tmp_dir)
self.device.mkDir(self.remote_tmp_dir)
if self.device.dirExists(self.remote_bin_dir):
self.device.removeDir(self.remote_bin_dir)
self.device.mkDir(self.remote_bin_dir)
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
elif self.options.local_lib:
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):
for root, dirs, files in os.walk(local_arm_lib):
for file in files:
if (file.endswith(".so")):
remote_file = posixpath.join(self.remote_bin_dir, file)
self.device.pushFile(os.path.join(root, file), remote_file)
def push_progs(self, progs):
for local_file in progs:
remote_file = posixpath.join(self.remote_bin_dir, os.path.basename(local_file))
self.device.pushFile(local_file, remote_file)
def build_environment(self):
env = self.build_core_environment()
env['LD_LIBRARY_PATH'] = self.remote_bin_dir
env["TMPDIR"]=self.remote_tmp_dir
env["HOME"]=self.remote_home_dir
env["MOZILLA_FIVE_HOME"] = self.remote_home_dir
env["MOZ_XRE_DIR"] = self.remote_bin_dir
if self.options.add_env:
for envdef in self.options.add_env:
envdef_parts = envdef.split("=", 1)
if len(envdef_parts) == 2:
env[envdef_parts[0]] = envdef_parts[1]
elif len(envdef_parts) == 1:
env[envdef_parts[0]] = ""
else:
self.log.warning("invalid --addEnv option skipped: %s" % envdef)
return env
def run_one_test(self, prog, env, symbols_path=None, interactive=False,
timeout_factor=1):
"""
Run a single C++ unit test program remotely.
Arguments:
* prog: The path to the test program to run.
* env: The environment to use for running the program.
* symbols_path: A path to a directory containing Breakpad-formatted
symbol files for producing stack traces on crash.
* timeout_factor: An optional test-specific timeout multiplier.
Return True if the program exits with a zero status, False otherwise.
"""
basename = os.path.basename(prog)
remote_bin = posixpath.join(self.remote_bin_dir, basename)
self.log.test_start(basename)
buf = StringIO.StringIO()
test_timeout = cppunittests.CPPUnitTests.TEST_PROC_TIMEOUT * timeout_factor
returncode = self.device.shell([remote_bin], buf, env=env, cwd=self.remote_home_dir,
timeout=test_timeout)
self.log.process_output(basename, "\n%s" % buf.getvalue(),
command=[remote_bin])
with mozfile.TemporaryDirectory() as tempdir:
self.device.getDirectory(self.remote_home_dir, tempdir)
if mozcrash.check_for_crashes(tempdir, symbols_path,
test_name=basename):
self.log.test_end(basename, status='CRASH', expected='PASS')
return False
result = returncode == 0
if not result:
self.log.test_end(basename, status='FAIL', expected='PASS',
message=("test failed with return code %d" %
returncode))
else:
self.log.test_end(basename, status='PASS', expected='PASS')
return result
class RemoteCPPUnittestOptions(cppunittests.CPPUnittestOptions):
def __init__(self):
cppunittests.CPPUnittestOptions.__init__(self)
defaults = {}
self.add_option("--deviceIP", action="store",
type = "string", dest = "device_ip",
help = "ip address of remote device to test")
defaults["device_ip"] = None
self.add_option("--devicePort", action="store",
type = "string", dest = "device_port",
help = "port of remote device to test")
defaults["device_port"] = 20701
self.add_option("--dm_trans", action="store",
type = "string", dest = "dm_trans",
help = "the transport to use to communicate with device: [adb|sut]; default=sut")
defaults["dm_trans"] = "sut"
self.add_option("--noSetup", action="store_false",
dest = "setup",
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("--with-b2g-emulator", action = "store",
type = "string", dest = "with_b2g_emulator",
help = "Start B2G Emulator (specify path to b2g home)")
self.add_option("--addEnv", action = "append",
type = "string", dest = "add_env",
help = "additional remote environment variable definitions (eg. --addEnv \"somevar=something\")")
defaults["add_env"] = None
self.set_defaults(**defaults)
def run_test_harness(options, args):
if options.with_b2g_emulator:
from mozrunner import B2GEmulatorRunner
runner = B2GEmulatorRunner(b2g_home=options.with_b2g_emulator)
runner.start()
if options.dm_trans == "adb":
if options.with_b2g_emulator:
# because we just started the emulator, we need more than the
# default number of retries here.
retryLimit = 50
else:
retryLimit = 5
try:
if options.device_ip:
dm = devicemanagerADB.DeviceManagerADB(options.device_ip, options.device_port, packageName=None, deviceRoot=options.remote_test_root, retryLimit=retryLimit)
else:
dm = devicemanagerADB.DeviceManagerADB(packageName=None, deviceRoot=options.remote_test_root, retryLimit=retryLimit)
except:
if options.with_b2g_emulator:
runner.cleanup()
runner.wait()
raise
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)
cppunittests.update_mozinfo()
progs = cppunittests.extract_unittests_from_args(args,
mozinfo.info,
options.manifest_path)
tester = RemoteCPPUnitTests(dm, options, [item[0] for item in progs])
try:
result = tester.run_tests(progs, options.xre_path, options.symbols_path)
finally:
if options.with_b2g_emulator:
runner.cleanup()
runner.wait()
return result
def main():
parser = RemoteCPPUnittestOptions()
mozlog.commandline.add_logging_group(parser)
options, args = parser.parse_args()
if not args:
print >>sys.stderr, """Usage: %s <test binary> [<test binary>...]""" % sys.argv[0]
sys.exit(1)
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)
log = mozlog.commandline.setup_logging("remotecppunittests", options,
{"tbpl": sys.stdout})
try:
result = run_test_harness(options, args)
except Exception, e:
log.error(str(e))
result = False
sys.exit(0 if result else 1)
if __name__ == '__main__':
main()