2012-05-21 15:12:37 +04:00
|
|
|
# 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/.
|
2010-03-24 20:51:17 +03:00
|
|
|
|
2014-07-11 16:15:29 +04:00
|
|
|
import os
|
2014-07-17 11:02:00 +04:00
|
|
|
import sys
|
|
|
|
import traceback
|
2010-02-25 22:10:39 +03:00
|
|
|
|
2015-02-13 22:42:02 +03:00
|
|
|
sys.path.insert(
|
|
|
|
0, os.path.abspath(
|
|
|
|
os.path.realpath(
|
|
|
|
os.path.dirname(__file__))))
|
2010-02-25 22:10:39 +03:00
|
|
|
|
|
|
|
from automation import Automation
|
2012-11-13 01:57:13 +04:00
|
|
|
from remoteautomation import RemoteAutomation, fennecLogcatFilters
|
2015-11-18 21:35:38 +03:00
|
|
|
from runtests import MochitestDesktop, MessageLogger
|
2015-04-30 20:47:01 +03:00
|
|
|
from mochitest_options import MochitestArgumentParser
|
2010-02-25 22:10:39 +03:00
|
|
|
|
2016-02-12 00:09:45 +03:00
|
|
|
import mozdevice
|
2013-10-08 23:14:38 +04:00
|
|
|
import mozinfo
|
2013-09-05 20:14:54 +04:00
|
|
|
|
2014-04-16 18:29:39 +04:00
|
|
|
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
|
2010-02-25 22:10:39 +03:00
|
|
|
|
2015-02-13 22:42:02 +03:00
|
|
|
|
2015-11-18 21:35:38 +03:00
|
|
|
# TODO inherit from MochitestBase instead
|
|
|
|
class MochiRemote(MochitestDesktop):
|
2010-02-25 22:10:39 +03:00
|
|
|
_automation = None
|
|
|
|
_dm = None
|
2012-01-08 03:41:08 +04:00
|
|
|
localProfile = None
|
2014-07-17 11:02:00 +04:00
|
|
|
logMessages = []
|
2010-02-25 22:10:39 +03:00
|
|
|
|
2014-08-13 20:03:00 +04:00
|
|
|
def __init__(self, automation, devmgr, options):
|
2015-11-18 21:35:38 +03:00
|
|
|
MochitestDesktop.__init__(self, options)
|
2014-08-13 20:03:00 +04:00
|
|
|
|
2010-02-25 22:10:39 +03:00
|
|
|
self._automation = automation
|
|
|
|
self._dm = devmgr
|
2013-09-23 18:47:48 +04:00
|
|
|
self.environment = self._automation.environment
|
2015-11-27 21:57:15 +03:00
|
|
|
self.remoteProfile = os.path.join(options.remoteTestRoot, "profile/")
|
|
|
|
self.remoteModulesDir = os.path.join(options.remoteTestRoot, "modules/")
|
2011-10-06 18:51:03 +04:00
|
|
|
self._automation.setRemoteProfile(self.remoteProfile)
|
2010-02-25 22:10:39 +03:00
|
|
|
self.remoteLog = options.remoteLogFile
|
2012-10-03 19:07:31 +04:00
|
|
|
self.localLog = options.logFile
|
2013-05-17 00:32:52 +04:00
|
|
|
self._automation.deleteANRs()
|
2014-08-11 21:55:28 +04:00
|
|
|
self._automation.deleteTombstones()
|
2014-03-14 22:25:41 +04:00
|
|
|
self.certdbNew = True
|
2014-08-14 02:23:26 +04:00
|
|
|
self.remoteNSPR = os.path.join(options.remoteTestRoot, "nspr")
|
2015-02-13 22:42:02 +03:00
|
|
|
self._dm.removeDir(self.remoteNSPR)
|
|
|
|
self._dm.mkDir(self.remoteNSPR)
|
|
|
|
self.remoteChromeTestDir = os.path.join(
|
|
|
|
options.remoteTestRoot,
|
|
|
|
"chrome")
|
|
|
|
self._dm.removeDir(self.remoteChromeTestDir)
|
|
|
|
self._dm.mkDir(self.remoteChromeTestDir)
|
2010-02-25 22:10:39 +03:00
|
|
|
|
2014-06-03 19:19:28 +04:00
|
|
|
def cleanup(self, options):
|
2012-10-15 18:15:19 +04:00
|
|
|
if self._dm.fileExists(self.remoteLog):
|
|
|
|
self._dm.getFile(self.remoteLog, self.localLog)
|
|
|
|
self._dm.removeFile(self.remoteLog)
|
|
|
|
else:
|
2015-02-13 22:42:02 +03:00
|
|
|
self.log.warning(
|
|
|
|
"Unable to retrieve log file (%s) from remote device" %
|
|
|
|
self.remoteLog)
|
2010-02-25 22:10:39 +03:00
|
|
|
self._dm.removeDir(self.remoteProfile)
|
2015-02-13 22:42:02 +03:00
|
|
|
self._dm.removeDir(self.remoteChromeTestDir)
|
2014-08-28 02:23:29 +04:00
|
|
|
blobberUploadDir = os.environ.get('MOZ_UPLOAD_DIR', None)
|
|
|
|
if blobberUploadDir:
|
|
|
|
self._dm.getDirectory(self.remoteNSPR, blobberUploadDir)
|
2015-11-18 21:35:38 +03:00
|
|
|
MochitestDesktop.cleanup(self, options)
|
2010-02-25 22:10:39 +03:00
|
|
|
|
2015-02-13 22:42:02 +03:00
|
|
|
def findPath(self, paths, filename=None):
|
2010-06-24 13:32:01 +04:00
|
|
|
for path in paths:
|
|
|
|
p = path
|
|
|
|
if filename:
|
|
|
|
p = os.path.join(p, filename)
|
|
|
|
if os.path.exists(self.getFullPath(p)):
|
|
|
|
return path
|
|
|
|
return None
|
2010-05-28 00:02:15 +04:00
|
|
|
|
2014-03-14 22:25:41 +04:00
|
|
|
def makeLocalAutomation(self):
|
2010-06-24 13:32:01 +04:00
|
|
|
localAutomation = Automation()
|
2011-02-24 22:45:42 +03:00
|
|
|
localAutomation.IS_WIN32 = False
|
|
|
|
localAutomation.IS_LINUX = False
|
|
|
|
localAutomation.IS_MAC = False
|
|
|
|
localAutomation.UNIXISH = False
|
|
|
|
hostos = sys.platform
|
2015-02-13 22:42:02 +03:00
|
|
|
if (hostos == 'mac' or hostos == 'darwin'):
|
2014-03-14 22:25:41 +04:00
|
|
|
localAutomation.IS_MAC = True
|
2011-02-24 22:45:42 +03:00
|
|
|
elif (hostos == 'linux' or hostos == 'linux2'):
|
2014-03-14 22:25:41 +04:00
|
|
|
localAutomation.IS_LINUX = True
|
|
|
|
localAutomation.UNIXISH = True
|
2011-02-24 22:45:42 +03:00
|
|
|
elif (hostos == 'win32' or hostos == 'win64'):
|
2014-03-14 22:25:41 +04:00
|
|
|
localAutomation.BIN_SUFFIX = ".exe"
|
|
|
|
localAutomation.IS_WIN32 = True
|
|
|
|
return localAutomation
|
|
|
|
|
|
|
|
# This seems kludgy, but this class uses paths from the remote host in the
|
|
|
|
# options, except when calling up to the base class, which doesn't
|
|
|
|
# understand the distinction. This switches out the remote values for local
|
|
|
|
# ones that the base class understands. This is necessary for the web
|
|
|
|
# server, SSL tunnel and profile building functions.
|
|
|
|
def switchToLocalPaths(self, options):
|
|
|
|
""" Set local paths in the options, return a function that will restore remote values """
|
|
|
|
remoteXrePath = options.xrePath
|
|
|
|
remoteProfilePath = options.profilePath
|
|
|
|
remoteUtilityPath = options.utilityPath
|
2010-06-24 13:32:01 +04:00
|
|
|
|
2014-03-14 22:25:41 +04:00
|
|
|
localAutomation = self.makeLocalAutomation()
|
|
|
|
paths = [
|
|
|
|
options.xrePath,
|
|
|
|
localAutomation.DIST_BIN,
|
|
|
|
self._automation._product,
|
|
|
|
os.path.join('..', self._automation._product)
|
|
|
|
]
|
2010-06-24 13:32:01 +04:00
|
|
|
options.xrePath = self.findPath(paths)
|
2015-02-13 22:42:02 +03:00
|
|
|
if options.xrePath is None:
|
|
|
|
self.log.error(
|
|
|
|
"unable to find xulrunner path for %s, please specify with --xre-path" %
|
|
|
|
os.name)
|
2010-06-24 13:32:01 +04:00
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
xpcshell = "xpcshell"
|
|
|
|
if (os.name == "nt"):
|
|
|
|
xpcshell += ".exe"
|
2014-03-14 22:25:41 +04:00
|
|
|
|
2013-09-12 19:02:48 +04:00
|
|
|
if options.utilityPath:
|
|
|
|
paths = [options.utilityPath, options.xrePath]
|
|
|
|
else:
|
|
|
|
paths = [options.xrePath]
|
2010-06-24 13:32:01 +04:00
|
|
|
options.utilityPath = self.findPath(paths, xpcshell)
|
2014-03-14 22:25:41 +04:00
|
|
|
|
2015-02-13 22:42:02 +03:00
|
|
|
if options.utilityPath is None:
|
|
|
|
self.log.error(
|
|
|
|
"unable to find utility path for %s, please specify with --utility-path" %
|
|
|
|
os.name)
|
2010-06-24 13:32:01 +04:00
|
|
|
sys.exit(1)
|
|
|
|
|
2013-01-25 23:35:15 +04:00
|
|
|
xpcshell_path = os.path.join(options.utilityPath, xpcshell)
|
|
|
|
if localAutomation.elf_arm(xpcshell_path):
|
2014-08-13 20:03:00 +04:00
|
|
|
self.log.error('xpcshell at %s is an ARM binary; please use '
|
2015-02-13 22:42:02 +03:00
|
|
|
'the --utility-path argument to specify the path '
|
|
|
|
'to a desktop version.' % xpcshell_path)
|
2013-09-05 20:14:56 +04:00
|
|
|
sys.exit(1)
|
2013-01-25 23:35:15 +04:00
|
|
|
|
2012-01-08 03:41:08 +04:00
|
|
|
if self.localProfile:
|
|
|
|
options.profilePath = self.localProfile
|
2014-03-14 22:25:41 +04:00
|
|
|
else:
|
2014-06-23 13:24:00 +04:00
|
|
|
options.profilePath = None
|
2014-03-14 22:25:41 +04:00
|
|
|
|
|
|
|
def fixup():
|
|
|
|
options.xrePath = remoteXrePath
|
|
|
|
options.utilityPath = remoteUtilityPath
|
|
|
|
options.profilePath = remoteProfilePath
|
|
|
|
|
|
|
|
return fixup
|
|
|
|
|
|
|
|
def startServers(self, options, debuggerInfo):
|
|
|
|
""" Create the servers on the host and start them up """
|
|
|
|
restoreRemotePaths = self.switchToLocalPaths(options)
|
2014-12-13 14:09:00 +03:00
|
|
|
# ignoreSSLTunnelExts is a workaround for bug 1109310
|
2015-11-18 21:35:38 +03:00
|
|
|
MochitestDesktop.startServers(
|
2015-02-13 22:42:02 +03:00
|
|
|
self,
|
|
|
|
options,
|
|
|
|
debuggerInfo,
|
|
|
|
ignoreSSLTunnelExts=True)
|
2014-03-14 22:25:41 +04:00
|
|
|
restoreRemotePaths()
|
|
|
|
|
|
|
|
def buildProfile(self, options):
|
|
|
|
restoreRemotePaths = self.switchToLocalPaths(options)
|
2015-11-27 21:57:15 +03:00
|
|
|
if options.testingModulesDir:
|
|
|
|
try:
|
|
|
|
self._dm.pushDir(options.testingModulesDir, self.remoteModulesDir)
|
2016-01-10 02:40:17 +03:00
|
|
|
self._dm.chmodDir(self.remoteModulesDir)
|
2016-02-12 00:09:45 +03:00
|
|
|
except mozdevice.DMError:
|
2015-11-27 21:57:15 +03:00
|
|
|
self.log.error(
|
|
|
|
"Automation Error: Unable to copy test modules to device.")
|
|
|
|
raise
|
|
|
|
savedTestingModulesDir = options.testingModulesDir
|
|
|
|
options.testingModulesDir = self.remoteModulesDir
|
|
|
|
else:
|
|
|
|
savedTestingModulesDir = None
|
2015-11-18 21:35:38 +03:00
|
|
|
manifest = MochitestDesktop.buildProfile(self, options)
|
2015-11-27 21:57:15 +03:00
|
|
|
if savedTestingModulesDir:
|
|
|
|
options.testingModulesDir = savedTestingModulesDir
|
2010-02-25 22:10:39 +03:00
|
|
|
self.localProfile = options.profilePath
|
2012-01-06 17:37:54 +04:00
|
|
|
self._dm.removeDir(self.remoteProfile)
|
2012-12-28 16:18:22 +04:00
|
|
|
|
Bug 795496 - Make mozdevice raise exceptions on error;r=ahal,jmaher
It turns out that relying on the user to check return codes for every
command was non-intuitive and resulted in many hard to trace bugs.
Now most functinos just return "None", and raise a DMError when there's an
exception. The exception to this are functions like dirExists, which now return
booleans, and throw exceptions on error. This is a fairly major refactor,
and also involved the following internal changes:
* Removed FileError and AgentError exceptions, replaced with DMError
(having to manage three different types of exceptions was confusing,
all the more so when we're raising them)
* Docstrings updated to remove references to return values where no
longer relevant
* pushFile no longer will create a directory to accomodate the file
if it doesn't exist (this makes it consistent with devicemanagerADB)
* dmSUT we validate the file, but assume that we get something back
from the agent, instead of falling back to manual validation in the
case that we didn't
* isDir and dirExists had the same intention, but different
implementations for dmSUT. Replaced the dmSUT impl of getDirectory
with that of isDir's (which was much simpler). Removed
isDir from devicemanager.py, since it wasn't used externally
* killProcess modified to check for process existence before running
(since the actual internal kill command will throw an exception
if the process doesn't exist)
In addition to all this, more unit tests have been added to test these
changes for devicemanagerSUT.
2012-10-04 19:28:07 +04:00
|
|
|
try:
|
|
|
|
self._dm.pushDir(options.profilePath, self.remoteProfile)
|
2016-01-10 02:40:17 +03:00
|
|
|
self._dm.chmodDir(self.remoteProfile)
|
2016-02-12 00:09:45 +03:00
|
|
|
except mozdevice.DMError:
|
2015-02-13 22:42:02 +03:00
|
|
|
self.log.error(
|
|
|
|
"Automation Error: Unable to copy profile to device.")
|
Bug 795496 - Make mozdevice raise exceptions on error;r=ahal,jmaher
It turns out that relying on the user to check return codes for every
command was non-intuitive and resulted in many hard to trace bugs.
Now most functinos just return "None", and raise a DMError when there's an
exception. The exception to this are functions like dirExists, which now return
booleans, and throw exceptions on error. This is a fairly major refactor,
and also involved the following internal changes:
* Removed FileError and AgentError exceptions, replaced with DMError
(having to manage three different types of exceptions was confusing,
all the more so when we're raising them)
* Docstrings updated to remove references to return values where no
longer relevant
* pushFile no longer will create a directory to accomodate the file
if it doesn't exist (this makes it consistent with devicemanagerADB)
* dmSUT we validate the file, but assume that we get something back
from the agent, instead of falling back to manual validation in the
case that we didn't
* isDir and dirExists had the same intention, but different
implementations for dmSUT. Replaced the dmSUT impl of getDirectory
with that of isDir's (which was much simpler). Removed
isDir from devicemanager.py, since it wasn't used externally
* killProcess modified to check for process existence before running
(since the actual internal kill command will throw an exception
if the process doesn't exist)
In addition to all this, more unit tests have been added to test these
changes for devicemanagerSUT.
2012-10-04 19:28:07 +04:00
|
|
|
raise
|
2010-03-16 01:47:34 +03:00
|
|
|
|
2014-03-14 22:25:41 +04:00
|
|
|
restoreRemotePaths()
|
2010-02-25 22:10:39 +03:00
|
|
|
options.profilePath = self.remoteProfile
|
|
|
|
return manifest
|
2014-03-14 22:25:41 +04:00
|
|
|
|
2016-01-25 17:55:57 +03:00
|
|
|
def addChromeToProfile(self, options):
|
|
|
|
manifest = MochitestDesktop.addChromeToProfile(self, options)
|
|
|
|
|
|
|
|
# Support Firefox (browser), B2G (shell), SeaMonkey (navigator), and Webapp
|
|
|
|
# Runtime (webapp).
|
|
|
|
if options.chrome:
|
|
|
|
# append overlay to chrome.manifest
|
|
|
|
chrome = "overlay chrome://browser/content/browser.xul chrome://mochikit/content/browser-test-overlay.xul"
|
|
|
|
path = os.path.join(options.profilePath, 'extensions', 'staged',
|
|
|
|
'mochikit@mozilla.org', 'chrome.manifest')
|
|
|
|
with open(path, "a") as f:
|
|
|
|
f.write(chrome)
|
|
|
|
return manifest
|
|
|
|
|
2011-07-27 03:13:20 +04:00
|
|
|
def buildURLOptions(self, options, env):
|
2010-02-25 22:10:39 +03:00
|
|
|
self.localLog = options.logFile
|
|
|
|
options.logFile = self.remoteLog
|
2014-08-15 23:42:00 +04:00
|
|
|
options.fileLevel = 'INFO'
|
2010-11-05 03:01:12 +03:00
|
|
|
options.profilePath = self.localProfile
|
2012-12-07 20:04:01 +04:00
|
|
|
env["MOZ_HIDE_RESULTS_TABLE"] = "1"
|
2015-11-18 21:35:38 +03:00
|
|
|
retVal = MochitestDesktop.buildURLOptions(self, options, env)
|
2012-12-28 16:18:22 +04:00
|
|
|
|
2015-07-09 21:30:01 +03:00
|
|
|
# we really need testConfig.js (for browser chrome)
|
|
|
|
try:
|
|
|
|
self._dm.pushDir(options.profilePath, self.remoteProfile)
|
2016-01-10 02:40:17 +03:00
|
|
|
self._dm.chmodDir(self.remoteProfile)
|
2016-02-12 00:09:45 +03:00
|
|
|
except mozdevice.DMError:
|
2015-07-09 21:30:01 +03:00
|
|
|
self.log.error(
|
|
|
|
"Automation Error: Unable to copy profile to device.")
|
|
|
|
raise
|
2010-11-05 03:01:12 +03:00
|
|
|
|
|
|
|
options.profilePath = self.remoteProfile
|
2010-02-25 22:10:39 +03:00
|
|
|
options.logFile = self.localLog
|
|
|
|
return retVal
|
|
|
|
|
2014-11-27 02:51:14 +03:00
|
|
|
def getChromeTestDir(self, options):
|
|
|
|
local = super(MochiRemote, self).getChromeTestDir(options)
|
|
|
|
local = os.path.join(local, "chrome")
|
|
|
|
remote = self.remoteChromeTestDir
|
|
|
|
if options.chrome:
|
|
|
|
self.log.info("pushing %s to %s on device..." % (local, remote))
|
|
|
|
self._dm.pushDir(local, remote)
|
|
|
|
return remote
|
2010-02-25 22:10:39 +03:00
|
|
|
|
2014-03-14 22:25:41 +04:00
|
|
|
def getLogFilePath(self, logFile):
|
2010-02-25 22:10:39 +03:00
|
|
|
return logFile
|
|
|
|
|
2013-06-25 04:15:40 +04:00
|
|
|
def printDeviceInfo(self, printLogcat=False):
|
2012-12-04 19:54:37 +04:00
|
|
|
try:
|
2013-06-25 04:15:40 +04:00
|
|
|
if printLogcat:
|
2015-02-13 22:42:02 +03:00
|
|
|
logcat = self._dm.getLogcat(
|
|
|
|
filterOutRegexps=fennecLogcatFilters)
|
|
|
|
self.log.info(
|
|
|
|
'\n' +
|
|
|
|
''.join(logcat).decode(
|
|
|
|
'utf-8',
|
|
|
|
'replace'))
|
2015-02-27 23:15:00 +03:00
|
|
|
self.log.info("Device info:")
|
|
|
|
devinfo = self._dm.getInfo()
|
|
|
|
for category in devinfo:
|
|
|
|
if type(devinfo[category]) is list:
|
|
|
|
self.log.info(" %s:" % category)
|
|
|
|
for item in devinfo[category]:
|
|
|
|
self.log.info(" %s" % item)
|
|
|
|
else:
|
|
|
|
self.log.info(" %s: %s" % (category, devinfo[category]))
|
2014-08-13 20:03:00 +04:00
|
|
|
self.log.info("Test root: %s" % self._dm.deviceRoot)
|
2016-02-12 00:09:45 +03:00
|
|
|
except mozdevice.DMError:
|
2014-08-13 20:03:00 +04:00
|
|
|
self.log.warning("Error getting device information")
|
2012-12-04 19:54:37 +04:00
|
|
|
|
2014-07-25 15:01:13 +04:00
|
|
|
def getGMPPluginPath(self, options):
|
2015-03-31 05:32:15 +03:00
|
|
|
# TODO: bug 1149374
|
2014-07-25 15:01:13 +04:00
|
|
|
return None
|
|
|
|
|
2013-09-16 22:44:25 +04:00
|
|
|
def buildBrowserEnv(self, options, debugger=False):
|
2015-11-18 21:35:38 +03:00
|
|
|
browserEnv = MochitestDesktop.buildBrowserEnv(
|
2015-02-13 22:42:02 +03:00
|
|
|
self,
|
|
|
|
options,
|
|
|
|
debugger=debugger)
|
2015-05-08 03:49:15 +03:00
|
|
|
# remove desktop environment not used on device
|
|
|
|
if "MOZ_WIN_INHERIT_STD_HANDLES_PRE_VISTA" in browserEnv:
|
|
|
|
del browserEnv["MOZ_WIN_INHERIT_STD_HANDLES_PRE_VISTA"]
|
|
|
|
if "XPCOM_MEM_BLOAT_LOG" in browserEnv:
|
|
|
|
del browserEnv["XPCOM_MEM_BLOAT_LOG"]
|
2015-11-18 21:35:38 +03:00
|
|
|
# override nsprLogs to avoid processing in MochitestDesktop base class
|
2014-08-14 02:23:26 +04:00
|
|
|
self.nsprLogs = None
|
2015-02-13 22:42:02 +03:00
|
|
|
browserEnv["NSPR_LOG_FILE"] = os.path.join(
|
|
|
|
self.remoteNSPR,
|
|
|
|
self.nsprLogName)
|
2012-10-16 21:25:23 +04:00
|
|
|
return browserEnv
|
|
|
|
|
2013-09-23 18:47:48 +04:00
|
|
|
def runApp(self, *args, **kwargs):
|
|
|
|
"""front-end automation.py's `runApp` functionality until FennecRunner is written"""
|
|
|
|
|
|
|
|
# automation.py/remoteautomation `runApp` takes the profile path,
|
|
|
|
# whereas runtest.py's `runApp` takes a mozprofile object.
|
|
|
|
if 'profileDir' not in kwargs and 'profile' in kwargs:
|
|
|
|
kwargs['profileDir'] = kwargs.pop('profile').profile
|
|
|
|
|
2016-01-25 17:55:57 +03:00
|
|
|
# remove args not supported by automation.py
|
|
|
|
kwargs.pop('marionette_args', None)
|
|
|
|
kwargs.pop('quiet', None)
|
2014-07-17 11:02:00 +04:00
|
|
|
|
2013-09-23 18:47:48 +04:00
|
|
|
return self._automation.runApp(*args, **kwargs)
|
|
|
|
|
2015-02-13 22:42:02 +03:00
|
|
|
|
2015-04-30 20:47:01 +03:00
|
|
|
def run_test_harness(options):
|
2014-08-13 20:03:00 +04:00
|
|
|
message_logger = MessageLogger(logger=None)
|
2014-07-17 11:02:00 +04:00
|
|
|
process_args = {'messageLogger': message_logger}
|
|
|
|
auto = RemoteAutomation(None, "fennec", processArgs=process_args)
|
2014-08-13 20:03:00 +04:00
|
|
|
|
2015-05-01 00:28:14 +03:00
|
|
|
if options is None:
|
|
|
|
raise ValueError("Invalid options specified, use --help for a list of valid options")
|
|
|
|
|
2015-08-11 15:25:00 +03:00
|
|
|
options.runByDir = False
|
2016-03-02 19:23:42 +03:00
|
|
|
# roboextender is used by mochitest-chrome tests like test_java_addons.html,
|
|
|
|
# but not by any plain mochitests
|
|
|
|
if not options.chrome:
|
|
|
|
options.extensionsToExclude.append('roboextender@mozilla.org')
|
2015-08-11 15:25:00 +03:00
|
|
|
|
2015-04-30 20:47:01 +03:00
|
|
|
dm = options.dm
|
|
|
|
auto.setDeviceManager(dm)
|
2014-08-13 20:03:00 +04:00
|
|
|
mochitest = MochiRemote(auto, dm, options)
|
|
|
|
|
|
|
|
log = mochitest.log
|
2014-08-29 18:37:17 +04:00
|
|
|
message_logger.logger = log
|
2014-08-13 20:03:00 +04:00
|
|
|
mochitest.message_logger = message_logger
|
|
|
|
|
2015-09-02 23:20:01 +03:00
|
|
|
# Check that Firefox is installed
|
|
|
|
expected = options.app.split('/')[-1]
|
|
|
|
installed = dm.shellCheckOutput(['pm', 'list', 'packages', expected])
|
|
|
|
if expected not in installed:
|
|
|
|
log.error("%s is not installed on this device" % expected)
|
|
|
|
return 1
|
|
|
|
|
2010-02-25 22:10:39 +03:00
|
|
|
productPieces = options.remoteProductName.split('.')
|
2015-02-13 22:42:02 +03:00
|
|
|
if (productPieces is not None):
|
2010-06-24 13:32:01 +04:00
|
|
|
auto.setProduct(productPieces[0])
|
2010-02-25 22:10:39 +03:00
|
|
|
else:
|
2010-06-24 13:32:01 +04:00
|
|
|
auto.setProduct(options.remoteProductName)
|
2014-02-02 19:11:22 +04:00
|
|
|
auto.setAppName(options.remoteappname)
|
2010-02-25 22:10:39 +03:00
|
|
|
|
2011-07-07 21:10:52 +04:00
|
|
|
logParent = os.path.dirname(options.remoteLogFile)
|
2015-02-13 22:42:02 +03:00
|
|
|
dm.mkDir(logParent)
|
2010-09-30 03:20:33 +04:00
|
|
|
auto.setRemoteLog(options.remoteLogFile)
|
2010-03-16 01:47:34 +03:00
|
|
|
auto.setServerInfo(options.webServer, options.httpPort, options.sslPort)
|
2011-02-23 22:38:56 +03:00
|
|
|
|
2015-08-06 16:27:47 +03:00
|
|
|
if options.log_mach is None:
|
|
|
|
mochitest.printDeviceInfo()
|
2012-07-26 04:45:36 +04:00
|
|
|
|
2013-10-08 23:14:38 +04:00
|
|
|
# Add Android version (SDK level) to mozinfo so that manifest entries
|
|
|
|
# can be conditional on android_version.
|
|
|
|
androidVersion = dm.shellCheckOutput(['getprop', 'ro.build.version.sdk'])
|
2015-02-13 22:42:02 +03:00
|
|
|
log.info(
|
|
|
|
"Android sdk version '%s'; will use this to filter manifests" %
|
|
|
|
str(androidVersion))
|
2013-10-08 23:14:38 +04:00
|
|
|
mozinfo.info['android_version'] = androidVersion
|
|
|
|
|
2014-07-11 23:29:30 +04:00
|
|
|
deviceRoot = dm.deviceRoot
|
2013-11-13 23:48:10 +04:00
|
|
|
if options.dmdPath:
|
|
|
|
dmdLibrary = "libdmd.so"
|
|
|
|
dmdPathOnDevice = os.path.join(deviceRoot, dmdLibrary)
|
|
|
|
dm.removeFile(dmdPathOnDevice)
|
|
|
|
dm.pushFile(os.path.join(options.dmdPath, dmdLibrary), dmdPathOnDevice)
|
|
|
|
options.dmdPath = deviceRoot
|
|
|
|
|
2013-11-21 20:33:43 +04:00
|
|
|
options.dumpOutputDirectory = deviceRoot
|
|
|
|
|
2011-02-23 22:38:56 +03:00
|
|
|
procName = options.app.split('/')[-1]
|
2014-02-02 19:11:22 +04:00
|
|
|
dm.killProcess(procName)
|
2012-10-24 21:34:33 +04:00
|
|
|
|
2015-07-09 21:30:01 +03:00
|
|
|
mochitest.nsprLogName = "nspr.log"
|
|
|
|
try:
|
|
|
|
dm.recordLogcat()
|
|
|
|
retVal = mochitest.runTests(options)
|
|
|
|
except:
|
|
|
|
log.error("Automation Error: Exception caught while running tests")
|
|
|
|
traceback.print_exc()
|
|
|
|
mochitest.stopServers()
|
2012-01-11 17:50:10 +04:00
|
|
|
try:
|
2015-07-09 21:30:01 +03:00
|
|
|
mochitest.cleanup(options)
|
2016-02-12 00:09:45 +03:00
|
|
|
except mozdevice.DMError:
|
2015-07-09 21:30:01 +03:00
|
|
|
# device error cleaning up... oh well!
|
|
|
|
pass
|
|
|
|
retVal = 1
|
|
|
|
|
2015-08-06 16:27:47 +03:00
|
|
|
if options.log_mach is None:
|
|
|
|
mochitest.printDeviceInfo(printLogcat=True)
|
2014-09-09 03:23:10 +04:00
|
|
|
|
2014-07-29 16:11:00 +04:00
|
|
|
message_logger.finish()
|
2012-01-08 03:41:08 +04:00
|
|
|
|
2014-09-09 03:23:11 +04:00
|
|
|
return retVal
|
|
|
|
|
2012-12-04 19:54:37 +04:00
|
|
|
|
2015-04-30 20:47:01 +03:00
|
|
|
def main(args=sys.argv[1:]):
|
|
|
|
parser = MochitestArgumentParser(app='android')
|
|
|
|
options = parser.parse_args(args)
|
|
|
|
|
|
|
|
return run_test_harness(options)
|
|
|
|
|
|
|
|
|
2010-02-25 22:10:39 +03:00
|
|
|
if __name__ == "__main__":
|
2015-04-30 20:47:01 +03:00
|
|
|
sys.exit(main())
|