blob: cd3af55e67b60eae665e36e0b6e52d5228aee370 [file] [log] [blame]
#!/usr/bin/env python
import os
import sys
import glob
import shutil
import zipfile
import site
site.addsitedir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../lib/python"))
from mozdevice import devicemanagerSUT as devicemanager
from sut_lib import getOurIP, calculatePort, setFlag, checkDeviceRoot, \
getDeviceTimestamp, setDeviceTimestamp, \
getResolution, waitForDevice, runCommand, log, powermanagement
# hwine: minor ugg - the flag files need to be global. Refactoring into
# a class would solve, but this module is scheduled for rewrite
def installOneApp(dm, devRoot, app_file_local_path, errorFile, logcat=True):
source = app_file_local_path
filename = os.path.basename(source)
target = os.path.join(devRoot, filename)
log.info("Installing %s" % target)
if dm.pushFile(source, target):
status = dm.installApp(target)
if status is None:
log.info('-' * 42)
log.info('installApp() done - gathering debug info')
dm.getInfo('process')
dm.getInfo('memory')
dm.getInfo('uptime')
if logcat:
try:
print dm._runCmds([{'cmd': 'exec su -c "logcat -d -v time *:W"'}])
except devicemanager.DMError, e:
setFlag(errorFile, "Remote Device Error: Exception hit while trying to run logcat: %s" % str(e))
return 1
else:
setFlag(errorFile,
"Remote Device Error: updateApp() call failed - exiting")
return 1
else:
setFlag(errorFile, "Remote Device Error: unable to push %s" % target)
return 1
return 0
def find_robocop():
# we hardcode the relative path to robocop.apk for bug 715215
# but it may not be unpacked at the time this runs, so be prepared
# to extract if needed (but use the extracted one if there)
extracted_location = 'build/tests/bin/robocop.apk'
self_extracted_location = 'build/robocop.apk'
actual_location = None
# for better error reporting
global errorFile
if os.path.exists(extracted_location):
actual_location = extracted_location
elif os.path.exists(self_extracted_location):
# already grabbed it in prior step
actual_location = self_extracted_location
else:
expected_zip_location = 'build/fennec*tests.zip'
matches = glob.glob(expected_zip_location)
if len(matches) == 1:
# try to grab the file we need from there, giving up if any
# assumption doesn't match
try:
archive = zipfile.ZipFile(matches[0], 'r')
apk_info = archive.getinfo('bin/robocop.apk')
# it's in the archive, extract to tmp dir - will be created
archive.extract(apk_info, 'build/tmp')
shutil.move(
'build/tmp/bin/robocop.apk', self_extracted_location)
actual_location = self_extracted_location
# got it
except Exception as e:
log.warning(
"(robocop): zip file not as expected: %s (%s)" % (e.message,
str(e.args)))
log.warning("(robocop): robocop.apk will not be installed")
else:
log.warning(
"(robocop): Didn't find just one %s; found '%s'" % (expected_zip_location,
str(matches)))
log.warning("(robocop): robocop.apk will not be installed")
return actual_location
def one_time_setup(ip_addr, major_source):
''' One time setup of state
ip_addr - of the device we want to install app at
major_source - we've hacked this script to install
may-also-be-needed tools, but the source we're asked to
install has the meta data we need
Side Effects:
global, needed for error reporting:
errorFile
'''
# set up the flag files, used throughout
cwd = os.getcwd()
global errorFile
errorFile = os.path.join(cwd, '..', 'error.flg')
deviceName = os.path.basename(cwd)
proxyIP = getOurIP()
proxyPort = calculatePort()
workdir = os.path.dirname(major_source)
inifile = os.path.join(workdir, 'fennec', 'application.ini')
remoteappini = os.path.join(workdir, 'talos', 'remoteapp.ini')
log.info('copying %s to %s' % (inifile, remoteappini))
runCommand(['cp', inifile, remoteappini])
log.info("connecting to: %s" % ip_addr)
dm = devicemanager.DeviceManagerSUT(ip_addr)
# Moar data!
dm.debug = 3
devRoot = checkDeviceRoot(dm)
if devRoot is None or devRoot == '/tests':
setFlag(errorFile, "Remote Device Error: devRoot from devicemanager [%s] is not correct - exiting" % devRoot)
return None, None
try:
log.info("%s, %s" % (proxyIP, proxyPort))
getDeviceTimestamp(dm)
setDeviceTimestamp(dm)
getDeviceTimestamp(dm)
dm.getInfo('process')
dm.getInfo('memory')
dm.getInfo('uptime')
width, height = getResolution(dm)
# adjust resolution down to allow fennec to install without memory
# issues
if (width == 1600 or height == 1200):
dm.adjustResolution(1024, 768, 'crt')
log.info('forcing device reboot')
if not powermanagement.soft_reboot_and_verify(device=deviceName, dm=dm, ipAddr=proxyIP, port=proxyPort):
return None, None
width, height = getResolution(dm)
if width != 1024 and height != 768:
setFlag(errorFile, "Remote Device Error: Resolution change failed. Should be %d/%d but is %d/%d" % (1024, 768, width, height))
return None, None
except devicemanager.AgentError, err:
log.error("remoteDeviceError: while doing one time setup for installation: %s" % err)
return None, None
return dm, devRoot
def main(argv):
if (len(argv) < 3):
print "usage: installApp.py <ip address> <localfilename> [<processName>]"
sys.exit(1)
# N.B. 3rd arg not used anywhere
ip_addr = argv[1]
path_to_main_apk = argv[2]
dm, devRoot = one_time_setup(ip_addr, path_to_main_apk)
if not dm:
return 1
# errorFile is already created globally in one_time_setup call above
if installOneApp(dm, devRoot, path_to_main_apk, errorFile):
return 1
# also install robocop if it's available
robocop_to_use = find_robocop()
if robocop_to_use is not None:
waitForDevice(dm)
# errorFile is already created globally in one_time_setup call above
if installOneApp(dm, devRoot, robocop_to_use, errorFile):
return 1
# make sure we're all the way back up before we finish
waitForDevice(dm)
return 0
if __name__ == '__main__':
# Stop buffering! (but not while testing)
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
sys.exit(main(sys.argv))