Bug 573263 - Refactor remote reftest to work on android, create shared remoteautomation class r=jmaher

This commit is contained in:
Clint Talbert 2010-06-24 02:32:01 -07:00
Родитель 31e4b12204
Коммит c1ea68a998
8 изменённых файлов: 342 добавлений и 245 удалений

Просмотреть файл

@ -50,6 +50,7 @@ import subprocess
import sys
import threading
import tempfile
import zipfile
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
sys.path.insert(0, SCRIPT_DIR)
@ -825,3 +826,48 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
ssltunnelProcess.kill()
return status
"""
Copies an "installed" extension into the extensions directory of the given profile
extensionSource - the source location of the extension files. This can be either
a directory or a path to an xpi file.
profileDir - the profile directory we are copying into. We will create the
"extensions" directory there if it doesn't exist
extensionID - the id of the extension to be used as the containing directory for the
extension, i.e.
this is the name of the folder in the <profileDir>/extensions/<extensionID>
"""
def installExtension(self, extensionSource, profileDir, extensionID):
if (not os.path.exists(extensionSource)):
self.log.info("INFO | automation.py | Cannot install extension no source at: %s", extensionSource)
if (not os.path.exists(profileDir)):
self.log.info("INFO | automation.py | Cannot install extension invalid profileDir at: %s", profileDir)
# See if we have an XPI or a directory
if (os.path.isfile(extensionSource)):
tmpd = tempfile.mkdtemp()
extrootdir = self.extractZip(extensionSource, tmpd)
else:
extrootdir = extensionSource
extnsdir = os.path.join(profileDir, "extensions")
extnshome = os.path.join(extnsdir, extensionID)
# Now we copy the extension source into the extnshome
shutil.copytree(extrootdir, extnshome)
def extractZip(self, filename, dest):
z = zipfile.ZipFile(filename, 'r')
for n in z.namelist():
fullpath = os.path.join(dest, n)
parentdir = os.path.dirname(fullpath)
if not os.path.isdir(parentdir):
os.makedirs(parentdir)
if (not n.endswith(os.sep)):
data = z.read(n)
f = open(fullpath, 'w')
f.write(data)
f.close()
z.close()
return dest

Просмотреть файл

@ -0,0 +1,144 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Joel Maher.
#
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Joel Maher <joel.maher@gmail.com> (Original Developer)
# Clint Talbert <cmtalbert@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
import time
import sys
import os
from automation import Automation
from devicemanager import DeviceManager
class RemoteAutomation(Automation):
_devicemanager = None
def __init__(self, deviceManager, appName = ''):
self._devicemanager = deviceManager
self._appName = appName
self._remoteProfile = None
# Default our product to fennec
self._product = "fennec"
Automation.__init__(self)
def setDeviceManager(self, deviceManager):
self._devicemanager = deviceManager
def setAppName(self, appName):
self._appName = appName
def setRemoteProfile(self, remoteProfile):
self._remoteProfile = remoteProfile
def setProduct(self, product):
self._product = product
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo):
# maxTime is used to override the default timeout, we should honor that
status = proc.wait(timeout = maxTime)
print proc.stdout
if (status == 1 and self._devicemanager.processExist(proc.procName)):
# Then we timed out, make sure Fennec is dead
proc.kill()
return status
def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs):
# If remote profile is specified, use that instead
if (self._remoteProfile):
profileDir = self._remoteProfile
cmd, args = Automation.buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs)
# Remove -foreground if it exists, if it doesn't this just returns
try:
args.remove('-foreground')
except:
pass
#TODO: figure out which platform require NO_EM_RESTART
# return app, ['--environ:NO_EM_RESTART=1'] + args
return app, args
def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
return self.RProcess(self._devicemanager, cmd, stdout, stderr, env, cwd)
# be careful here as this inner class doesn't have access to outer class members
class RProcess(object):
# device manager process
dm = None
def __init__(self, dm, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
self.dm = dm
print "going to launch process: " + str(self.dm.host)
self.proc = dm.launchProcess(cmd)
exepath = cmd[0]
name = exepath.split('/')[-1]
self.procName = name
# Setting timeout at 1 hour since on a remote device this takes much longer
self.timeout = 3600
time.sleep(15)
@property
def pid(self):
hexpid = self.dm.processExist(self.procName)
if (hexpid == '' or hexpid == None):
hexpid = "0x0"
return int(hexpid, 0)
@property
def stdout(self):
return self.dm.getFile(self.proc)
def wait(self, timeout = None):
timer = 0
interval = 5
if timeout == None:
timeout = self.timeout
while (self.dm.processExist(self.procName)):
time.sleep(interval)
timer += interval
if (timer > timeout):
break
if (timer >= timeout):
return 1
return 0
def kill(self):
self.dm.killProcess(self.procName)

Просмотреть файл

@ -79,6 +79,7 @@ _HARNESS_FILES = \
$(topsrcdir)/build/mobile/devicemanager.py \
$(topsrcdir)/build/automationutils.py \
$(topsrcdir)/build/poster.zip \
$(topsrcdir)/build/mobile/remoteautomation.py \
$(NULL)
$(_DEST_DIR):

Просмотреть файл

@ -47,83 +47,7 @@ from runreftest import RefTest
from runreftest import ReftestOptions
from automation import Automation
from devicemanager import DeviceManager
class RemoteAutomation(Automation):
_devicemanager = None
def __init__(self, deviceManager, product = ''):
self._devicemanager = deviceManager
self._product = product
Automation.__init__(self)
def setDeviceManager(self, deviceManager):
self._devicemanager = deviceManager
def setProduct(self, productName):
self._product = productName
def setRemoteApp(self, remoteAppName):
self._remoteAppName = remoteAppName
def setTestRoot(self, testRoot):
self._testRoot = testRoot
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime):
status = proc.wait()
print proc.stdout
# todo: consider pulling log file from remote
return status
def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs):
remoteProfileDir = self._testRoot + 'profile'
cmd, args = Automation.buildCommandLine(self, app, debuggerInfo, remoteProfileDir, testURL, extraArgs)
return app, ['--environ:NO_EM_RESTART=1'] + args
def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
return self.RProcess(self._devicemanager, self._remoteAppName, cmd, stdout, stderr, env, cwd)
class RProcess(object):
#device manager process
dm = None
def __init__(self, dm, appName, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
self.dm = dm
print "going to launch process: " + str(self.dm.host)
self.proc = dm.launchProcess(cmd)
self.procName = appName
# Setting this at 1 hour since remote testing is much slower
self.timeout = 3600
time.sleep(5)
@property
def pid(self):
hexpid = self.dm.processExist(self.procName)
if (hexpid == '' or hexpid == None):
hexpid = 0
return int(hexpid, 0)
@property
def stdout(self):
return self.dm.getFile(self.proc)
def wait(self, timeout = None):
timer = 0
if timeout == None:
timeout = self.timeout
while (self.dm.process.isAlive()):
time.sleep(1)
timer += 1
if (timer > timeout):
break
if (timer >= timeout):
return 1
return 0
def kill(self):
self.dm.killProcess(self.procName)
from remoteautomation import RemoteAutomation
class RemoteOptions(ReftestOptions):
def __init__(self, automation):
@ -132,38 +56,80 @@ class RemoteOptions(ReftestOptions):
defaults = {}
defaults["logFile"] = "reftest.log"
# app, xrePath and utilityPath variables are set in main function
defaults["testRoot"] = "/tests/"
defaults["remoteTestRoot"] = None
defaults["app"] = ""
defaults["xrePath"] = ""
defaults["utilityPath"] = ""
self.add_option("--device", action="store",
type = "string", dest = "device",
self.add_option("--remote-app-path", action="store",
type = "string", dest = "remoteAppPath",
help = "Path to remote executable relative to device root using only forward slashes. Either this or app must be specified, but not both.")
defaults["remoteAppPath"] = None
self.add_option("--deviceIP", action="store",
type = "string", dest = "deviceIP",
help = "ip address of remote device to test")
defaults["device"] = None
defaults["deviceIP"] = None
self.add_option("--devicePort", action="store",
type = "string", dest = "devicePort",
help = "port of remote device to test")
defaults["devicePort"] = 27020
defaults["devicePort"] = 20701
self.add_option("--remoteProductName", action="store",
self.add_option("--remote-product-name", action="store",
type = "string", dest = "remoteProductName",
help = "Name of remote product to test - either fennec or firefox, defaults to fennec")
help = "Name of product to test - either fennec or firefox, defaults to fennec")
defaults["remoteProductName"] = "fennec"
self.add_option("--remoteAppName", action="store",
type = "string", dest = "remoteAppName",
help = "Executable name for remote device, OS dependent, defaults to fennec.exe")
defaults["remoteAppName"] = "fennec.exe"
self.add_option("--remote-webserver", action="store",
type = "string", dest = "remoteWebServer",
help = "IP Address of the webserver hosting the reftest content")
defaults["remoteWebServer"] = "127.0.0.1"
defaults["remoteWebServer"] = None
self.add_option("--http-port", action = "store",
type = "string", dest = "httpPort",
help = "port of the web server for http traffic")
defaults["httpPort"] = automation.DEFAULT_HTTP_PORT
self.add_option("--ssl-port", action = "store",
type = "string", dest = "sslPort",
help = "Port for https traffic to the web server")
defaults["sslPort"] = automation.DEFAULT_SSL_PORT
self.add_option("--remote-logfile", action="store",
type = "string", dest = "remoteLogFile",
help = "Name of log file on the device relative to device root. PLEASE USE ONLY A FILENAME.")
defaults["remoteLogFile"] = "reftest.log"
self.set_defaults(**defaults)
def verifyRemoteOptions(self, options):
# Ensure our defaults are set properly for everything we can infer
options.remoteTestRoot = self._automation._devicemanager.getDeviceRoot() + '/reftest'
options.remoteProfile = options.remoteTestRoot + "/profile"
# One of remoteAppPath (relative path to application) or the app (executable) must be
# set, but not both. If both are set, we destroy the user's selection for app
# so instead of silently destroying a user specificied setting, we error.
if (options.remoteAppPath and options.app):
print "ERROR: You cannot specify both the remoteAppPath and the app"
return None
elif (options.remoteAppPath):
options.app = options.remoteTestRoot + "/" + options.remoteAppPath
elif (options.app == None):
# Neither remoteAppPath nor app are set -- error
print "ERROR: You must specify either appPath or app"
return None
if (options.xrePath == None):
print "ERROR: You must specify the path to the controller xre directory"
return None
# 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'
return options
class RemoteReftest(RefTest):
remoteApp = ''
@ -172,39 +138,32 @@ class RemoteReftest(RefTest):
self._devicemanager = devicemanager
self.scriptDir = scriptDir
self.remoteApp = options.app
self.remoteTestRoot = options.testRoot
self.remoteProfileDir = options.testRoot + 'profile'
self.remoteTestRoot = options.remoteTestRoot
def createReftestProfile(self, options, profileDir):
RefTest.createReftestProfile(self, options, profileDir)
self.remoteTestRoot += "reftest/"
# install the reftest extension bits into the remoteProfile
profileExtensionsPath = os.path.join(profileDir, "extensions")
reftestExtensionPath = self.remoteTestRoot.replace('/', '\\')
extFile = open(os.path.join(profileExtensionsPath, "reftest@mozilla.org"), "w")
extFile.write(reftestExtensionPath)
extFile.close()
if (self._devicemanager.pushDir(profileDir, self.remoteProfileDir) == None):
if (self._devicemanager.pushDir(profileDir, options.remoteProfile) == None):
raise devicemanager.FileError("Failed to copy profiledir to device")
if (self._devicemanager.pushDir(self.scriptDir + '/reftest', self.remoteTestRoot) == None):
raise devicemanager.FileError("Failed to copy extension dir to device")
def copyExtraFilesToProfile(self, options, profileDir):
RefTest.copyExtraFilesToProfile(self, options, profileDir)
if (self._devicemanager.pushDir(profileDir, self.remoteProfileDir) == None):
raise devicemanager.FileError("Failed to copy extra files in profile dir to device")
if (self._devicemanager.pushDir(profileDir, options.remoteProfile) == None):
raise devicemanager.FileError("Failed to copy extra files to device")
def registerExtension(self, browserEnv, options, profileDir):
"""
It appears that we do not need to do the extension registration on winmo.
This is something we should look into for winmo as the -silent option isn't working
"""
pass
def registerExtension(self, browserEnv, options, profileDir, extraArgs = ['-silent'] ):
self.automation.log.info("REFTEST INFO | runreftest.py | Performing extension manager registration: start.\n")
# Because our startProcess code doesn't return until fennec starts we just give it
# a maxTime of 20 secs before timing it out and ensuring it is dead.
# Besides registering the extension, this works around fennec bug 570027
status = self.automation.runApp(None, browserEnv, options.app, profileDir,
extraArgs,
utilityPath = options.utilityPath,
xrePath=options.xrePath,
symbolsPath=options.symbolsPath,
maxTime = 20)
# We don't care to call |processLeakLog()| for this step.
self.automation.log.info("\nREFTEST INFO | runreftest.py | Performing extension manager registration: end.")
def getManifestPath(self, path):
return path
@ -220,22 +179,24 @@ def main():
parser = RemoteOptions(automation)
options, args = parser.parse_args()
if (options.device == None):
if (options.deviceIP == None):
print "Error: you must provide a device IP to connect to via the --device option"
sys.exit(1)
if options.remoteAppName.rfind('/') < 0:
options.app = options.testRoot + options.remoteProductName + '/'
options.app += str(options.remoteAppName)
options.xrePath = options.testRoot + options.remoteProductName + '/xulrunner'
options.utilityPath = options.testRoot + options.remoteProductName + '/bin'
dm = DeviceManager(options.device, options.devicePort)
dm = DeviceManager(options.deviceIP, options.devicePort)
automation.setDeviceManager(dm)
if (options.remoteProductName != None):
automation.setProduct(options.remoteProductName)
automation.setRemoteApp(options.remoteAppName)
automation.setTestRoot(options.testRoot)
# Set up the defaults and ensure options are set
options = parser.verifyRemoteOptions(options)
if (options == None):
print "ERROR: Invalid options specified, use --help for a list of valid options"
sys.exit(1)
automation.setAppName(options.app)
automation.setRemoteProfile(options.remoteProfile)
reftest = RemoteReftest(automation, dm, options, SCRIPT_DIRECTORY)
if (options.remoteWebServer == "127.0.0.1"):

Просмотреть файл

@ -93,12 +93,10 @@ class RefTest(object):
prefsFile.close()
# install the reftest extension bits into the profile
profileExtensionsPath = os.path.join(profileDir, "extensions")
os.mkdir(profileExtensionsPath)
reftestExtensionPath = os.path.join(SCRIPT_DIRECTORY, "reftest")
extFile = open(os.path.join(profileExtensionsPath, "reftest@mozilla.org"), "w")
extFile.write(reftestExtensionPath)
extFile.close()
self.automation.installExtension(os.path.join(SCRIPT_DIRECTORY, "reftest"),
profileDir,
"reftest@mozilla.org")
def registerExtension(self, browserEnv, options, profileDir, extraArgs = ['-silent']):
# run once with -silent to let the extension manager do its thing
@ -149,7 +147,6 @@ class RefTest(object):
# then again to actually run reftest
self.automation.log.info("REFTEST INFO | runreftest.py | Running tests: start.\n")
reftestlist = self.getManifestPath(manifest)
status = self.automation.runApp(None, browserEnv, options.app, profileDir,
["-reftest", reftestlist],
utilityPath = options.utilityPath,
@ -179,14 +176,15 @@ class RefTest(object):
class ReftestOptions(OptionParser):
def __init__(self, automation):
self._automation = automation
OptionParser.__init__(self)
defaults = {}
# we want to pass down everything from automation.__all__
addCommonOptions(self,
defaults=dict(zip(automation.__all__,
[getattr(automation, x) for x in automation.__all__])))
automation.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),
@ -208,10 +206,10 @@ class ReftestOptions(OptionParser):
"than the given number")
self.add_option("--utility-path",
action = "store", type = "string", dest = "utilityPath",
default = automation.DIST_BIN,
default = self._automation.DIST_BIN,
help = "absolute path to directory containing utility "
"programs (xpcshell, ssltunnel, certutil)")
defaults["utilityPath"] = automation.DIST_BIN
defaults["utilityPath"] = self._automation.DIST_BIN
self.add_option("--total-chunks",
type = "int", dest = "totalChunks",

Просмотреть файл

@ -66,6 +66,7 @@ _SERV_FILES = \
$(topsrcdir)/build/mobile/devicemanager.py \
$(topsrcdir)/build/automationutils.py \
$(topsrcdir)/build/poster.zip \
$(topsrcdir)/build/mobile/remoteautomation.py \
gen_template.pl \
server.js \
harness-a11y.xul \

Просмотреть файл

@ -341,7 +341,10 @@ class MochitestServer:
c = urllib2.urlopen(self.shutdownURL)
c.read()
c.close()
self._process.wait()
rtncode = self._process.poll()
if (rtncode == None):
self._process.terminate()
except:
self._process.kill()

Просмотреть файл

@ -44,100 +44,24 @@ import tempfile
sys.path.insert(0, os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0]))))
from automation import Automation
from remoteautomation import RemoteAutomation
from runtests import Mochitest
from runtests import MochitestOptions
from runtests import MochitestServer
import devicemanager
class RemoteAutomation(Automation):
_devicemanager = None
def __init__(self, deviceManager, product):
self._devicemanager = deviceManager
self._product = product
Automation.__init__(self)
def setDeviceManager(self, deviceManager):
self._devicemanager = deviceManager
def setProduct(self, productName):
self._product = productName
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo):
status = proc.wait()
print proc.stdout
# todo: consider pulling log file from remote
return status
def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs):
cmd, args = Automation.buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs)
# Remove -foreground if it exists, if it doesn't this just returns
try:
args.remove('-foreground')
except:
pass
#TODO: figure out which platform require NO_EM_RESTART
# return app, ['--environ:NO_EM_RESTART=1'] + args
return app, args
def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
return self.RProcess(self._devicemanager, self._product, cmd, stdout, stderr, env, cwd)
# be careful here as this inner class doesn't have access to outer class members
class RProcess(object):
# device manager process
dm = None
def __init__(self, dm, product, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
self.dm = dm
print "going to launch process: " + str(self.dm.host)
self.proc = dm.launchProcess(cmd)
exepath = cmd[0]
name = exepath.split('/')[-1]
self.procName = name
# Setting timeout at 1 hour since on a remote device this takes much longer
self.timeout = 3600
time.sleep(15)
@property
def pid(self):
hexpid = self.dm.processExist(self.procName)
if (hexpid == '' or hexpid == None):
hexpid = "0x0"
return int(hexpid, 0)
@property
def stdout(self):
return self.dm.getFile(self.proc)
def wait(self, timeout = None):
timer = 0
interval = 5
if timeout == None:
timeout = self.timeout
while (self.dm.processExist(self.procName)):
time.sleep(interval)
timer += interval
if (timer > timeout):
break
if (timer >= timeout):
return 1
return 0
def kill(self):
self.dm.killProcess(self.procName)
class RemoteOptions(MochitestOptions):
def __init__(self, automation, scriptdir, **kwargs):
defaults = {}
MochitestOptions.__init__(self, automation, scriptdir)
self.add_option("--remote-app-path", action="store",
type = "string", dest = "remoteAppPath",
help = "Path to remote executable relative to device root using only forward slashes. Either this or app must be specified but not both")
defaults["remoteAppPath"] = None
self.add_option("--deviceIP", action="store",
type = "string", dest = "deviceIP",
help = "ip address of remote device to test")
@ -148,7 +72,7 @@ class RemoteOptions(MochitestOptions):
help = "port of remote device to test")
defaults["devicePort"] = 20701
self.add_option("--remoteProductName", action="store",
self.add_option("--remote-product-name", action="store",
type = "string", dest = "remoteProductName",
help = "The executable's name of remote product to test - either fennec or firefox, defaults to fennec")
defaults["remoteProductName"] = "fennec"
@ -185,12 +109,13 @@ class RemoteOptions(MochitestOptions):
def verifyRemoteOptions(self, options, automation):
options.remoteTestRoot = automation._devicemanager.getDeviceRoot()
options.utilityPath = options.remoteTestRoot + "/bin"
options.certPath = options.remoteTestRoot + "/certs"
if options.remoteWebServer == None:
if os.name != "nt":
if options.remoteWebServer == None and os.name != "nt":
options.remoteWebServer = get_lan_ip()
else:
elif os.name == "nt":
print "ERROR: you must specify a remoteWebServer ip address\n"
return None
@ -205,14 +130,18 @@ class RemoteOptions(MochitestOptions):
# Set up our options that we depend on based on the above
productRoot = options.remoteTestRoot + "/" + automation._product
# Set this only if the user hasn't set it
if (options.utilityPath == None):
options.utilityPath = productRoot + "/bin"
# If provided, use cli value, otherwise reset as remoteTestRoot
if (options.app == None):
options.app = productRoot + "/" + options.remoteProductName
# remoteAppPath or app must be specified to find the product to launch
if (options.remoteAppPath and options.app):
print "ERROR: You cannot specify both the remoteAppPath and the app setting"
return None
elif (options.remoteAppPath):
options.app = options.remoteTestRoot + "/" + options.remoteAppPath
elif (options.app == None):
# Neither remoteAppPath nor app are set -- error
print "ERROR: You must specify either appPath or app"
return None
# Only reset the xrePath if it wasn't provided
if (options.xrePath == None):
@ -303,9 +232,6 @@ class MochiRemote(Mochitest):
def stopWebServer(self, options):
self.server.stop()
def runExtensionRegistration(self, options, browserEnv):
pass
def buildProfile(self, options):
manifest = Mochitest.buildProfile(self, options)
self.localProfile = options.profilePath
@ -315,6 +241,23 @@ class MochiRemote(Mochitest):
options.profilePath = self.remoteProfile
return manifest
def runExtensionRegistration(self, options, browserEnv):
""" run once with -silent to let the extension manager do its thing
and then exit the app
We do this on every run because we need to work around bug 570027
"""
self._automation.log.info("INFO | runtestsremote.py | Performing extension manager registration: start.\n")
# Don't care about this |status|: |runApp()| reporting it should be enough.
# Because process() doesn't return until fennec starts, we just give it a fudge
# factor of 20s before timing it out and killing it.
status = self._automation.runApp(None, browserEnv, options.app,
options.profilePath, ["-silent"],
utilityPath = options.utilityPath,
xrePath = options.xrePath,
symbolsPath=options.symbolsPath,
maxTime = 20)
# We don't care to call |processLeakLog()| for this step.
self._automation.log.info("\nINFO | runtestsremote.py | Performing extension manager registration: end.")
def buildURLOptions(self, options):
self.localLog = options.logFile
options.logFile = self.remoteLog