From 1cf91fdbe116547aeb63281acd048d1ea55e750a Mon Sep 17 00:00:00 2001 From: Andrew Halberstadt Date: Fri, 24 Jan 2014 10:34:01 -0500 Subject: [PATCH] Bug 916350 - Make it possible to run reftests on b2g desktop, r=jgriffin,ted --- layout/tools/reftest/Makefile.in | 1 + layout/tools/reftest/b2g_desktop.py | 170 ++++++++++++++++++ layout/tools/reftest/b2g_start_script.js | 9 +- layout/tools/reftest/reftest.js | 9 + layout/tools/reftest/remotereftest.py | 20 +-- layout/tools/reftest/runreftest.py | 66 ++++--- layout/tools/reftest/runreftestb2g.py | 60 ++++--- testing/mozbase/mozrunner/mozrunner/local.py | 8 +- testing/mozbase/mozrunner/mozrunner/runner.py | 9 +- 9 files changed, 277 insertions(+), 75 deletions(-) create mode 100644 layout/tools/reftest/b2g_desktop.py diff --git a/layout/tools/reftest/Makefile.in b/layout/tools/reftest/Makefile.in index 5424b94e0ee3..f8263a1848b4 100644 --- a/layout/tools/reftest/Makefile.in +++ b/layout/tools/reftest/Makefile.in @@ -45,6 +45,7 @@ _HARNESS_FILES = \ $(srcdir)/runreftest.py \ $(srcdir)/remotereftest.py \ $(srcdir)/runreftestb2g.py \ + $(srcdir)/b2g_desktop.py \ $(srcdir)/b2g_start_script.js \ automation.py \ $(topsrcdir)/testing/mozbase/mozdevice/mozdevice/devicemanager.py \ diff --git a/layout/tools/reftest/b2g_desktop.py b/layout/tools/reftest/b2g_desktop.py new file mode 100644 index 000000000000..6d05410ad84a --- /dev/null +++ b/layout/tools/reftest/b2g_desktop.py @@ -0,0 +1,170 @@ +# 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/. +from __future__ import print_function, unicode_literals + +import json +import os +import signal +import sys +import threading + +here = os.path.abspath(os.path.dirname(__file__)) + +from runreftest import RefTest, ReftestOptions + +from marionette import Marionette +from mozprocess import ProcessHandler +from mozrunner import FirefoxRunner +import mozinfo +import mozlog + +log = mozlog.getLogger('REFTEST') + +class B2GDesktopReftest(RefTest): + def __init__(self, marionette): + RefTest.__init__(self) + self.last_test = os.path.basename(__file__) + self.marionette = marionette + self.profile = None + self.runner = None + self.test_script = os.path.join(here, 'b2g_start_script.js') + self.timeout = None + + def run_marionette_script(self): + assert(self.marionette.wait_for_port()) + self.marionette.start_session() + self.marionette.set_context(self.marionette.CONTEXT_CHROME) + + if os.path.isfile(self.test_script): + f = open(self.test_script, 'r') + self.test_script = f.read() + f.close() + self.marionette.execute_script(self.test_script) + + def run_tests(self, test_path, options): + reftestlist = self.getManifestPath(test_path) + if not reftestlist.startswith('file://'): + reftestlist = 'file://%s' % reftestlist + + self.profile = self.create_profile(options, reftestlist, + profile_to_clone=options.profile) + env = self.buildBrowserEnv(options, self.profile.profile) + kp_kwargs = { 'processOutputLine': [self._on_output], + 'onTimeout': [self._on_timeout], + 'kill_on_timeout': False } + + if not options.debugger: + if not options.timeout: + if mozinfo.info['debug']: + options.timeout = 420 + else: + options.timeout = 300 + self.timeout = options.timeout + 30.0 + + log.info("%s | Running tests: start.", os.path.basename(__file__)) + cmd, args = self.build_command_line(options.app, + ignore_window_size=options.ignoreWindowSize) + self.runner = FirefoxRunner(profile=self.profile, + binary=cmd, + cmdargs=args, + env=env, + process_class=ProcessHandler, + symbols_path=options.symbolsPath, + kp_kwargs=kp_kwargs) + + status = 0 + try: + self.runner.start(outputTimeout=self.timeout) + log.info("%s | Application pid: %d", + os.path.basename(__file__), + self.runner.process_handler.pid) + + # kick starts the reftest harness + self.run_marionette_script() + status = self.runner.wait() + finally: + self.runner.check_for_crashes(test_name=self.last_test) + self.runner.cleanup() + + if status > 0: + log.testFail("%s | application terminated with exit code %s", + self.last_test, status) + elif status < 0: + log.info("%s | application killed with signal %s", + self.last_test, -status) + + log.info("%s | Running tests: end.", os.path.basename(__file__)) + return status + + def create_profile(self, options, reftestlist, profile_to_clone=None): + profile = RefTest.createReftestProfile(self, options, reftestlist, + profile_to_clone=profile_to_clone) + + prefs = {} + # Turn off the locale picker screen + prefs["browser.firstrun.show.localepicker"] = False + prefs["browser.homescreenURL"] = "app://test-container.gaiamobile.org/index.html" + prefs["browser.manifestURL"] = "app://test-container.gaiamobile.org/manifest.webapp" + prefs["browser.tabs.remote"] = False + prefs["dom.ipc.tabs.disabled"] = False + prefs["dom.mozBrowserFramesEnabled"] = True + prefs["font.size.inflation.emPerLine"] = 0 + prefs["font.size.inflation.minTwips"] = 0 + prefs["network.dns.localDomains"] = "app://test-container.gaiamobile.org" + prefs["reftest.browser.iframe.enabled"] = False + prefs["reftest.remote"] = False + prefs["reftest.uri"] = "%s" % reftestlist + # Set a future policy version to avoid the telemetry prompt. + prefs["toolkit.telemetry.prompted"] = 999 + prefs["toolkit.telemetry.notifiedOptOut"] = 999 + + # Set the extra prefs. + profile.set_preferences(prefs) + return profile + + def build_command_line(self, app, ignore_window_size=False): + cmd = os.path.abspath(app) + args = [] + + if not ignore_window_size: + args.extend(['--screen', '800x1000']) + return cmd, args + + def _on_output(self, line): + print(line) + # TODO use structured logging + if "TEST-START" in line and "|" in line: + self.last_test = line.split("|")[1].strip() + + def _on_timeout(self): + msg = "%s | application timed out after %s seconds with no output" + log.testFail(msg % (self.last_test, self.timeout)) + + # kill process to get a stack + self.runner.stop(sig=signal.SIGABRT) + + +def run_desktop_reftests(parser, options, args): + kwargs = {} + if options.marionette: + host, port = options.marionette.split(':') + kwargs['host'] = host + kwargs['port'] = int(port) + marionette = Marionette.getMarionetteOrExit(**kwargs) + + reftest = B2GDesktopReftest(marionette) + + options = ReftestOptions.verifyCommonOptions(parser, options, reftest) + if options == None: + sys.exit(1) + + # add a -bin suffix if b2g-bin exists, but just b2g was specified + if options.app[-4:] != '-bin': + if os.path.isfile("%s-bin" % options.app): + options.app = "%s-bin" % options.app + + if options.desktop and not options.profile: + raise Exception("must specify --profile when specifying --desktop") + + sys.exit(reftest.run_tests(args[0], options)) diff --git a/layout/tools/reftest/b2g_start_script.js b/layout/tools/reftest/b2g_start_script.js index e4369045757a..bade89e5321f 100644 --- a/layout/tools/reftest/b2g_start_script.js +++ b/layout/tools/reftest/b2g_start_script.js @@ -2,9 +2,6 @@ * 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/. */ -let serverAddr = __marionetteParams[0]; -let serverPort = __marionetteParams[1]; - function setDefaultPrefs() { // This code sets the preferences for extension-based reftest; for // command-line based reftest they are set in function handler_handle in @@ -44,6 +41,12 @@ function setDefaultPrefs() { } function setPermissions() { + if (__marionetteParams.length < 2) { + return; + } + + let serverAddr = __marionetteParams[0]; + let serverPort = __marionetteParams[1]; let perms = Cc["@mozilla.org/permissionmanager;1"] .getService(Ci.nsIPermissionManager); let ioService = Cc["@mozilla.org/network/io-service;1"] diff --git a/layout/tools/reftest/reftest.js b/layout/tools/reftest/reftest.js index 69c8a927660d..f29d038b1e24 100644 --- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest.js @@ -394,6 +394,15 @@ function InitAndStartRefTests() if (gRemote) { gServer = null; } else { + // not all gecko applications autoregister xpcom components + if (CC["@mozilla.org/server/jshttp;1"] === undefined) { + var file = CC["@mozilla.org/file/directory_service;1"]. + getService(CI.nsIProperties).get("ProfD", CI.nsIFile); + file.appendRelativePath("extensions/reftest@mozilla.org/chrome.manifest"); + + registrar = Components.manager.QueryInterface(CI.nsIComponentRegistrar); + registrar.autoRegister(file); + } gServer = CC["@mozilla.org/server/jshttp;1"]. createInstance(CI.nsIHttpServer); } diff --git a/layout/tools/reftest/remotereftest.py b/layout/tools/reftest/remotereftest.py index 6d8131d61a1f..d733e0dd3047 100644 --- a/layout/tools/reftest/remotereftest.py +++ b/layout/tools/reftest/remotereftest.py @@ -108,7 +108,7 @@ class RemoteOptions(ReftestOptions): # Ensure our defaults are set properly for everything we can infer if not options.remoteTestRoot: - options.remoteTestRoot = self._automation._devicemanager.getDeviceRoot() + '/reftest' + options.remoteTestRoot = self.automation._devicemanager.getDeviceRoot() + '/reftest' options.remoteProfile = options.remoteTestRoot + "/profile" # Verify that our remotewebserver is set properly @@ -166,8 +166,8 @@ class RemoteOptions(ReftestOptions): options.httpdPath = os.path.join(options.utilityPath, "components") # TODO: Copied from main, but I think these are no longer used in a post xulrunner world - #options.xrePath = options.remoteTestRoot + self._automation._product + '/xulrunner' - #options.utilityPath = options.testRoot + self._automation._product + '/bin' + #options.xrePath = options.remoteTestRoot + self.automation._product + '/xulrunner' + #options.utilityPath = options.testRoot + self.automation._product + '/bin' return options class ReftestServer: @@ -178,7 +178,7 @@ class ReftestServer: it's own class and use it in both remote and non-remote testing. """ def __init__(self, automation, options, scriptDir): - self._automation = automation + self.automation = automation self._utilityPath = options.utilityPath self._xrePath = options.xrePath self._profileDir = options.serverProfilePath @@ -192,9 +192,9 @@ class ReftestServer: def start(self): "Run the Refest server, returning the process ID of the server." - env = self._automation.environment(xrePath = self._xrePath) + env = self.automation.environment(xrePath = self._xrePath) env["XPCOM_DEBUG_BREAK"] = "warn" - if self._automation.IS_WIN32: + if self.automation.IS_WIN32: env["PATH"] = env["PATH"] + ";" + self._xrePath args = ["-g", self._xrePath, @@ -205,21 +205,21 @@ class ReftestServer: "-f", os.path.join(self.scriptDir, "server.js")] xpcshell = os.path.join(self._utilityPath, - "xpcshell" + self._automation.BIN_SUFFIX) + "xpcshell" + self.automation.BIN_SUFFIX) if not os.access(xpcshell, os.F_OK): raise Exception('xpcshell not found at %s' % xpcshell) - if self._automation.elf_arm(xpcshell): + if self.automation.elf_arm(xpcshell): raise Exception('xpcshell at %s is an ARM binary; please use ' 'the --utility-path argument to specify the path ' 'to a desktop version.' % xpcshell) - self._process = self._automation.Process([xpcshell] + args, env = env) + self._process = self.automation.Process([xpcshell] + args, env = env) pid = self._process.pid if pid < 0: print "TEST-UNEXPECTED-FAIL | remotereftests.py | Error starting server." return 2 - self._automation.log.info("INFO | remotereftests.py | Server pid: %d", pid) + self.automation.log.info("INFO | remotereftests.py | Server pid: %d", pid) if (self.pidFile != ""): f = open(self.pidFile + ".xpcshell.pid", 'w') diff --git a/layout/tools/reftest/runreftest.py b/layout/tools/reftest/runreftest.py index 906034f46c89..3a982086a03d 100644 --- a/layout/tools/reftest/runreftest.py +++ b/layout/tools/reftest/runreftest.py @@ -6,22 +6,27 @@ Runs the reftest test harness. """ -import re -import sys -import shutil -import os -import threading -import subprocess +from optparse import OptionParser import collections +import json import multiprocessing +import os +import re +import shutil +import subprocess +import sys +import threading + SCRIPT_DIRECTORY = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0]))) sys.path.insert(0, SCRIPT_DIRECTORY) from automation import Automation -from automationutils import * -from optparse import OptionParser -from tempfile import mkdtemp - +from automationutils import ( + addCommonOptions, + getDebuggerInfo, + isURL, + processLeakLog +) import mozprofile def categoriesToRegex(categoryList): @@ -129,11 +134,11 @@ class RefTest(object): return '"%s"' % re.sub(r'([\\"])', r'\\\1', s) def createReftestProfile(self, options, manifest, server='localhost', - special_powers=True): + special_powers=True, profile_to_clone=None): """ Sets up a profile for reftest. 'manifest' is the path to the reftest.list file we want to test with. This is used in - the remote subclass in remotereftest.py so we can write it to a preference for the + the remote subclass in remotereftest.py so we can write it to a preference for the bootstrap extension. """ @@ -184,11 +189,14 @@ class RefTest(object): for f in options.extensionsToInstall: addons.append(self.getFullPath(f)) - profile = mozprofile.profile.Profile( - addons=addons, - preferences=prefs, - locations=locations, - ) + kwargs = { 'addons': addons, + 'preferences': prefs, + 'locations': locations } + if profile_to_clone: + profile = mozprofile.Profile.clone(profile_to_clone, **kwargs) + else: + profile = mozprofile.Profile(**kwargs) + self.copyExtraFilesToProfile(options, profile) return profile @@ -201,7 +209,7 @@ class RefTest(object): if ix <= 0: print "Error: syntax error in --setenv=" + v return None - browserEnv[v[:ix]] = v[ix + 1:] + browserEnv[v[:ix]] = v[ix + 1:] # Enable leaks detection to its own log file. self.leakLogFile = os.path.join(profileDir, "runreftest_leaks.log") @@ -338,16 +346,16 @@ class RefTest(object): class ReftestOptions(OptionParser): - def __init__(self, automation): - self._automation = automation + def __init__(self, automation=None): + self.automation = automation or Automation() OptionParser.__init__(self) defaults = {} # we want to pass down everything from automation.__all__ - addCommonOptions(self, - defaults=dict(zip(self._automation.__all__, - [getattr(self._automation, x) for x in self._automation.__all__]))) - self._automation.addCommonOptions(self) + addCommonOptions(self, + defaults=dict(zip(self.automation.__all__, + [getattr(self.automation, x) for x in self.automation.__all__]))) + self.automation.addCommonOptions(self) self.add_option("--appname", action = "store", type = "string", dest = "app", default = os.path.join(SCRIPT_DIRECTORY, automation.DEFAULT_APP), @@ -356,8 +364,8 @@ class ReftestOptions(OptionParser): action = "append", dest = "extraProfileFiles", default = [], help = "copy specified files/dirs to testing profile") - self.add_option("--timeout", - action = "store", dest = "timeout", type = "int", + self.add_option("--timeout", + action = "store", dest = "timeout", type = "int", default = 5 * 60, # 5 minutes per bug 479518 help = "reftest will timeout in specified number of seconds. [default %default s].") self.add_option("--leak-threshold", @@ -369,10 +377,10 @@ class ReftestOptions(OptionParser): "than the given number") self.add_option("--utility-path", action = "store", type = "string", dest = "utilityPath", - default = self._automation.DIST_BIN, + default = self.automation.DIST_BIN, help = "absolute path to directory containing utility " "programs (xpcshell, ssltunnel, certutil)") - defaults["utilityPath"] = self._automation.DIST_BIN + defaults["utilityPath"] = self.automation.DIST_BIN self.add_option("--total-chunks", type = "int", dest = "totalChunks", @@ -389,7 +397,7 @@ class ReftestOptions(OptionParser): default = None, help = "file to log output to in addition to stdout") defaults["logFile"] = None - + self.add_option("--skip-slow-tests", dest = "skipSlowTests", action = "store_true", help = "skip tests marked as slow when running") diff --git a/layout/tools/reftest/runreftestb2g.py b/layout/tools/reftest/runreftestb2g.py index 2f51f786e004..2b2ae81b792f 100644 --- a/layout/tools/reftest/runreftestb2g.py +++ b/layout/tools/reftest/runreftestb2g.py @@ -9,11 +9,11 @@ import tempfile import traceback # We need to know our current directory so that we can serve our test files from it. -SCRIPT_DIRECTORY = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0]))) -sys.path.insert(0, SCRIPT_DIRECTORY) +here = os.path.abspath(os.path.dirname(__file__)) from automation import Automation from b2gautomation import B2GRemoteAutomation +from b2g_desktop import run_desktop_reftests from runreftest import RefTest from runreftest import ReftestOptions from remotereftest import ReftestServer @@ -21,7 +21,6 @@ from remotereftest import ReftestServer from mozdevice import DeviceManagerADB, DMError from marionette import Marionette - class B2GOptions(ReftestOptions): def __init__(self, automation=None, **kwargs): @@ -111,6 +110,15 @@ class B2GOptions(ReftestOptions): type = "string", dest = "httpdPath", help = "path to the httpd.js file") defaults["httpdPath"] = None + self.add_option("--profile", action="store", + type="string", dest="profile", + help="for desktop testing, the path to the " + "gaia profile to use") + defaults["profile"] = None + self.add_option("--desktop", action="store_true", + dest="desktop", + help="Run the tests on a B2G desktop build") + defaults["desktop"] = False defaults["remoteTestRoot"] = "/data/local/tests" defaults["logFile"] = "reftest.log" defaults["autorun"] = True @@ -125,16 +133,16 @@ class B2GOptions(ReftestOptions): self.error("Cannot run parallel tests here") if not options.remoteTestRoot: - options.remoteTestRoot = self._automation._devicemanager.getDeviceRoot() + "/reftest" + options.remoteTestRoot = self.automation._devicemanager.getDeviceRoot() + "/reftest" options.remoteProfile = options.remoteTestRoot + "/profile" - productRoot = options.remoteTestRoot + "/" + self._automation._product - if options.utilityPath == self._automation.DIST_BIN: + productRoot = options.remoteTestRoot + "/" + self.automation._product + if options.utilityPath == self.automation.DIST_BIN: options.utilityPath = productRoot + "/bin" if options.remoteWebServer == None: if os.name != "nt": - options.remoteWebServer = self._automation.getLanIp() + options.remoteWebServer = self.automation.getLanIp() else: print "ERROR: you must specify a --remote-webserver=\n" return None @@ -209,23 +217,20 @@ class ProfileConfigParser(ConfigParser.RawConfigParser): fp.write("%s\n" % (key)) fp.write("\n") +class B2GRemoteReftest(RefTest): -class B2GReftest(RefTest): - - _automation = None _devicemanager = None localProfile = None remoteApp = '' profile = None def __init__(self, automation, devicemanager, options, scriptDir): - self._automation = automation - RefTest.__init__(self, self._automation) + RefTest.__init__(self, automation) self._devicemanager = devicemanager self.runSSLTunnel = False self.remoteTestRoot = options.remoteTestRoot self.remoteProfile = options.remoteProfile - self._automation.setRemoteProfile(self.remoteProfile) + self.automation.setRemoteProfile(self.remoteProfile) self.localLogName = options.localLogName self.remoteLogFile = options.remoteLogFile self.bundlesDir = '/system/b2g/distribution/bundles' @@ -235,7 +240,7 @@ class B2GReftest(RefTest): self.originalProfilesIni = None self.scriptDir = scriptDir self.SERVER_STARTUP_TIMEOUT = 90 - if self._automation.IS_DEBUG_BUILD: + if self.automation.IS_DEBUG_BUILD: self.SERVER_STARTUP_TIMEOUT = 180 def cleanup(self, profileDir): @@ -259,13 +264,13 @@ class B2GReftest(RefTest): # Restore the original profiles.ini. if self.originalProfilesIni: try: - if not self._automation._is_emulator: + if not self.automation._is_emulator: self.restoreProfilesIni() os.remove(self.originalProfilesIni) except: pass - if not self._automation._is_emulator: + if not self.automation._is_emulator: self._devicemanager.removeFile(self.remoteLogFile) self._devicemanager.removeDir(self.remoteProfile) self._devicemanager.removeDir(self.remoteTestRoot) @@ -276,7 +281,7 @@ class B2GReftest(RefTest): # We've restored the original profile, so reboot the device so that # it gets picked up. - self._automation.rebootDevice() + self.automation.rebootDevice() RefTest.cleanup(self, profileDir) if getattr(self, 'pidFile', '') != '': @@ -317,8 +322,8 @@ class B2GReftest(RefTest): paths = [options.xrePath, localAutomation.DIST_BIN, - self._automation._product, - os.path.join('..', self._automation._product)] + self.automation._product, + os.path.join('..', self.automation._product)] options.xrePath = self.findPath(paths) if options.xrePath == None: print "ERROR: unable to find xulrunner path for %s, please specify with --xre-path" % (os.name) @@ -338,7 +343,7 @@ class B2GReftest(RefTest): sys.exit(1) xpcshell = os.path.join(options.utilityPath, xpcshell) - if self._automation.elf_arm(xpcshell): + if self.automation.elf_arm(xpcshell): raise Exception('xpcshell at %s is an ARM binary; please use ' 'the --utility-path argument to specify the path ' 'to a desktop version.' % xpcshell) @@ -367,7 +372,6 @@ class B2GReftest(RefTest): if hasattr(self, 'server'): self.server.stop() - def restoreProfilesIni(self): # restore profiles.ini on the device to its previous state if not self.originalProfilesIni or not os.access(self.originalProfilesIni, os.F_OK): @@ -470,6 +474,7 @@ class B2GReftest(RefTest): def getManifestPath(self, path): return path + def run_remote_reftests(parser, options, args): auto = B2GRemoteAutomation(None, "fennec", context_chrome=True) @@ -525,11 +530,11 @@ def run_remote_reftests(parser, options, args): return 1 auto.setProduct("b2g") - auto.test_script = os.path.join(SCRIPT_DIRECTORY, 'b2g_start_script.js') + auto.test_script = os.path.join(here, 'b2g_start_script.js') auto.test_script_args = [options.remoteWebServer, options.httpPort] auto.logFinish = "REFTEST TEST-START | Shutdown" - reftest = B2GReftest(auto, dm, options, SCRIPT_DIRECTORY) + reftest = B2GRemoteReftest(auto, dm, options, here) options = parser.verifyCommonOptions(options, reftest) logParent = os.path.dirname(options.remoteLogFile) @@ -538,14 +543,14 @@ def run_remote_reftests(parser, options, args): auto.setServerInfo(options.webServer, options.httpPort, options.sslPort) # Hack in a symbolic link for jsreftest - os.system("ln -s %s %s" % (os.path.join('..', 'jsreftest'), os.path.join(SCRIPT_DIRECTORY, 'jsreftest'))) + os.system("ln -s %s %s" % (os.path.join('..', 'jsreftest'), os.path.join(here, 'jsreftest'))) # Dynamically build the reftest URL if possible, beware that args[0] should exist 'inside' the webroot manifest = args[0] - if os.path.exists(os.path.join(SCRIPT_DIRECTORY, args[0])): + if os.path.exists(os.path.join(here, args[0])): manifest = "http://%s:%s/%s" % (options.remoteWebServer, options.httpPort, args[0]) elif os.path.exists(args[0]): - manifestPath = os.path.abspath(args[0]).split(SCRIPT_DIRECTORY)[1].strip('/') + manifestPath = os.path.abspath(args[0]).split(here)[1].strip('/') manifest = "http://%s:%s/%s" % (options.remoteWebServer, options.httpPort, manifestPath) else: print "ERROR: Could not find test manifest '%s'" % manifest @@ -582,6 +587,9 @@ def run_remote_reftests(parser, options, args): def main(args=sys.argv[1:]): parser = B2GOptions() options, args = parser.parse_args(args) + + if options.desktop: + return run_desktop_reftests(parser, options, args) return run_remote_reftests(parser, options, args) diff --git a/testing/mozbase/mozrunner/mozrunner/local.py b/testing/mozbase/mozrunner/mozrunner/local.py index d5c11d7f93f9..9f69fef04da2 100644 --- a/testing/mozbase/mozrunner/mozrunner/local.py +++ b/testing/mozbase/mozrunner/mozrunner/local.py @@ -73,16 +73,16 @@ class LocalRunner(Runner): @classmethod def create(cls, binary=None, cmdargs=None, env=None, kp_kwargs=None, profile_args=None, - clean_profile=True, process_class=None): + clean_profile=True, process_class=None, **kwargs): profile = cls.profile_class(**(profile_args or {})) return cls(profile, binary=binary, cmdargs=cmdargs, env=env, kp_kwargs=kp_kwargs, - clean_profile=clean_profile, process_class=process_class) + clean_profile=clean_profile, process_class=process_class, **kwargs) def __init__(self, profile, binary, cmdargs=None, env=None, - kp_kwargs=None, clean_profile=None, process_class=None): + kp_kwargs=None, clean_profile=None, process_class=None, **kwargs): super(LocalRunner, self).__init__(profile, clean_profile=clean_profile, kp_kwargs=kp_kwargs, - process_class=process_class, env=env) + process_class=process_class, env=env, **kwargs) # find the binary self.binary = binary diff --git a/testing/mozbase/mozrunner/mozrunner/runner.py b/testing/mozbase/mozrunner/mozrunner/runner.py index aa2626222f84..203605a0306e 100755 --- a/testing/mozbase/mozrunner/mozrunner/runner.py +++ b/testing/mozbase/mozrunner/mozrunner/runner.py @@ -1,8 +1,9 @@ #!/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 import subprocess import traceback @@ -38,7 +39,6 @@ class Runner(object): self.log = mozlog.getLogger('MozRunner') self.symbols_path = symbols_path - @abstractmethod def start(self, *args, **kwargs): """ Run the process @@ -112,7 +112,10 @@ class Runner(object): if getattr(self, 'profile', False): self.profile.reset() - def check_for_crashes(self, dump_directory, test_name=None): + def check_for_crashes(self, dump_directory=None, test_name=None): + if not dump_directory: + dump_directory = os.path.join(self.profile.profile, 'minidumps') + crashed = False try: crashed = mozcrash.check_for_crashes(dump_directory,