Bug 563860 - update runtestsremote.py to start webserver automatically and to work on android better r=jmaher
This commit is contained in:
Родитель
7be883d20b
Коммит
25660290ed
|
@ -54,86 +54,25 @@ class FileError(Exception):
|
|||
def __str__(self):
|
||||
return self.msg
|
||||
|
||||
class myProc(Thread):
|
||||
def __init__(self, hostip, hostport, cmd, new_line = True, sleeptime = 0):
|
||||
self.cmdline = cmd
|
||||
self.newline = new_line
|
||||
self.sleep = sleeptime
|
||||
self.host = hostip
|
||||
self.port = hostport
|
||||
Thread.__init__(self)
|
||||
|
||||
def run(self):
|
||||
promptre =re.compile('.*\$\>.$')
|
||||
data = ""
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
except:
|
||||
return None
|
||||
|
||||
try:
|
||||
s.connect((self.host, int(self.port)))
|
||||
except:
|
||||
s.close()
|
||||
return None
|
||||
|
||||
try:
|
||||
s.recv(1024)
|
||||
except:
|
||||
s.close()
|
||||
return None
|
||||
|
||||
for cmd in self.cmdline:
|
||||
if (cmd == 'quit'): break
|
||||
if self.newline: cmd += '\r\n'
|
||||
try:
|
||||
s.send(cmd)
|
||||
except:
|
||||
s.close()
|
||||
return None
|
||||
|
||||
time.sleep(int(self.sleep))
|
||||
|
||||
found = False
|
||||
while (found == False):
|
||||
try:
|
||||
temp = s.recv(1024)
|
||||
except:
|
||||
s.close()
|
||||
return None
|
||||
|
||||
lines = temp.split('\n')
|
||||
for line in lines:
|
||||
if (promptre.match(line)):
|
||||
found = True
|
||||
data += temp
|
||||
|
||||
try:
|
||||
s.send('quit\r\n')
|
||||
except:
|
||||
s.close()
|
||||
return None
|
||||
try:
|
||||
s.close()
|
||||
except:
|
||||
return None
|
||||
return data
|
||||
|
||||
class DeviceManager:
|
||||
host = ''
|
||||
port = 0
|
||||
debug = 3
|
||||
_redo = False
|
||||
deviceRoot = '/tests'
|
||||
deviceRoot = None
|
||||
tempRoot = os.getcwd()
|
||||
base_prompt = '\$\>'
|
||||
prompt_sep = '\x00'
|
||||
prompt_regex = '.*' + base_prompt + prompt_sep
|
||||
|
||||
def __init__(self, host, port = 27020):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self._sock = None
|
||||
self.getDeviceRoot()
|
||||
|
||||
def sendCMD(self, cmdline, newline = True, sleep = 0):
|
||||
promptre = re.compile('.*\$\>.$')
|
||||
promptre = re.compile(self.prompt_regex + '$')
|
||||
|
||||
# TODO: any commands that don't output anything and quit need to match this RE
|
||||
pushre = re.compile('^push .*$')
|
||||
|
@ -169,6 +108,7 @@ class DeviceManager:
|
|||
|
||||
try:
|
||||
self._sock.send(cmd)
|
||||
if (self.debug >= 4): print "send cmd: " + str(cmd)
|
||||
except:
|
||||
self._redo = True
|
||||
self._sock.close()
|
||||
|
@ -181,7 +121,7 @@ class DeviceManager:
|
|||
time.sleep(int(sleep))
|
||||
found = False
|
||||
while (found == False):
|
||||
if (self.debug >= 3): print "recv'ing..."
|
||||
if (self.debug >= 4): print "recv'ing..."
|
||||
|
||||
try:
|
||||
temp = self._sock.recv(1024)
|
||||
|
@ -211,16 +151,16 @@ class DeviceManager:
|
|||
|
||||
# take a data blob and strip instances of the prompt '$>\x00'
|
||||
def stripPrompt(self, data):
|
||||
promptre = re.compile('.*\$\>.*')
|
||||
promptre = re.compile(self.prompt_regex + '.*')
|
||||
retVal = []
|
||||
lines = data.split('\n')
|
||||
for line in lines:
|
||||
try:
|
||||
while (promptre.match(line)):
|
||||
pieces = line.split('\x00')
|
||||
index = pieces.index("$>")
|
||||
pieces = line.split(self.prompt_sep)
|
||||
index = pieces.index('$>')
|
||||
pieces.pop(index)
|
||||
line = '\x00'.join(pieces)
|
||||
line = self.prompt_sep.join(pieces)
|
||||
except(ValueError):
|
||||
pass
|
||||
retVal.append(line)
|
||||
|
@ -229,19 +169,16 @@ class DeviceManager:
|
|||
|
||||
|
||||
def pushFile(self, localname, destname):
|
||||
if (self.debug >= 2):
|
||||
print "in push file with: " + localname + ", and: " + destname
|
||||
if (self.debug >= 2): print "in push file with: " + localname + ", and: " + destname
|
||||
if (self.validateFile(destname, localname) == True):
|
||||
if (self.debug >= 2):
|
||||
print "files are validated"
|
||||
if (self.debug >= 2): print "files are validated"
|
||||
return ''
|
||||
|
||||
if self.mkDirs(destname) == None:
|
||||
print "unable to make dirs: " + destname
|
||||
return None
|
||||
|
||||
if (self.debug >= 2):
|
||||
print "sending: push " + destname
|
||||
if (self.debug >= 2): print "sending: push " + destname
|
||||
|
||||
# sleep 5 seconds / MB
|
||||
filesize = os.path.getsize(localname)
|
||||
|
@ -252,13 +189,11 @@ class DeviceManager:
|
|||
f.close()
|
||||
retVal = self.sendCMD(['push ' + destname + '\r\n', data], newline = False, sleep = sleepTime)
|
||||
if (retVal == None):
|
||||
if (self.debug >= 2):
|
||||
print "Error in sendCMD, not validating push"
|
||||
if (self.debug >= 2): print "Error in sendCMD, not validating push"
|
||||
return None
|
||||
|
||||
if (self.validateFile(destname, localname) == False):
|
||||
if (self.debug >= 2):
|
||||
print "file did not copy as expected"
|
||||
if (self.debug >= 2): print "file did not copy as expected"
|
||||
return None
|
||||
|
||||
return retVal
|
||||
|
@ -286,7 +221,6 @@ class DeviceManager:
|
|||
for root, dirs, files in os.walk(localDir):
|
||||
parts = root.split(localDir)
|
||||
for file in files:
|
||||
print "examining file: " + file
|
||||
remoteRoot = remoteDir + '/' + parts[1]
|
||||
remoteName = remoteRoot + '/' + file
|
||||
if (parts[1] == ""): remoteRoot = remoteDir
|
||||
|
@ -346,7 +280,7 @@ class DeviceManager:
|
|||
|
||||
|
||||
def getProcessList(self):
|
||||
data = self.sendCMD(['ps', 'quit'], sleep = 3)
|
||||
data = self.sendCMD(['ps'], sleep = 3)
|
||||
if (data == None):
|
||||
return None
|
||||
|
||||
|
@ -355,13 +289,14 @@ class DeviceManager:
|
|||
files = []
|
||||
for line in lines:
|
||||
if (line.strip() != ''):
|
||||
pidproc = line.strip().split(' ')
|
||||
pidproc = line.strip().split()
|
||||
if (len(pidproc) == 2):
|
||||
files += [[pidproc[0], pidproc[1]]]
|
||||
|
||||
elif (len(pidproc) == 3):
|
||||
#android returns <userID> <procID> <procName>
|
||||
files += [[pidproc[1], pidproc[2], pidproc[0]]]
|
||||
return files
|
||||
|
||||
|
||||
def getMemInfo(self):
|
||||
data = self.sendCMD(['mems', 'quit'])
|
||||
if (data == None):
|
||||
|
@ -375,29 +310,40 @@ class DeviceManager:
|
|||
|
||||
def fireProcess(self, appname):
|
||||
if (self.debug >= 2): print "FIRE PROC: '" + appname + "'"
|
||||
self.process = myProc(self.host, self.port, ['exec ' + appname, 'quit'])
|
||||
self.process.start()
|
||||
|
||||
if (self.processExist(appname) != ''):
|
||||
print "WARNING: process %s appears to be running already\n" % appname
|
||||
|
||||
self.sendCMD(['exec ' + appname])
|
||||
|
||||
#NOTE: we sleep for 30 seconds to allow the application to startup
|
||||
time.sleep(30)
|
||||
|
||||
self.process = self.processExist(appname)
|
||||
if (self.debug >= 4): print "got pid: " + str(self.process) + " for process: " + str(appname)
|
||||
|
||||
def launchProcess(self, cmd, outputFile = "process.txt", cwd = ''):
|
||||
if (outputFile == "process.txt"):
|
||||
outputFile = self.getDeviceRoot() + '/' + "process.txt"
|
||||
|
||||
|
||||
cmdline = subprocess.list2cmdline(cmd)
|
||||
self.fireProcess(cmdline + " > " + outputFile)
|
||||
handle = outputFile
|
||||
|
||||
|
||||
return handle
|
||||
|
||||
#hardcoded: sleep interval of 5 seconds, timeout of 10 minutes
|
||||
def communicate(self, process, timeout = 600):
|
||||
interval = 5
|
||||
timed_out = True
|
||||
if (timeout > 0):
|
||||
total_time = 0
|
||||
while total_time < timeout:
|
||||
time.sleep(1)
|
||||
time.sleep(interval)
|
||||
if (not self.poll(process)):
|
||||
timed_out = False
|
||||
break
|
||||
total_time += 1
|
||||
total_time += interval
|
||||
|
||||
if (timed_out == True):
|
||||
return None
|
||||
|
@ -407,7 +353,7 @@ class DeviceManager:
|
|||
|
||||
def poll(self, process):
|
||||
try:
|
||||
if (not self.process.isAlive()):
|
||||
if (self.processExist(process) == None):
|
||||
return None
|
||||
return 1
|
||||
except:
|
||||
|
@ -420,10 +366,11 @@ class DeviceManager:
|
|||
def processExist(self, appname):
|
||||
pid = ''
|
||||
|
||||
pieces = appname.split('/')
|
||||
app = pieces[-1]
|
||||
pieces = appname.split(' ')
|
||||
parts = pieces[0].split('/')
|
||||
app = parts[-1]
|
||||
procre = re.compile('.*' + app + '.*')
|
||||
|
||||
|
||||
procList = self.getProcessList()
|
||||
if (procList == None):
|
||||
return None
|
||||
|
@ -442,7 +389,6 @@ class DeviceManager:
|
|||
return True
|
||||
|
||||
def getTempDir(self):
|
||||
promptre = re.compile('.*\$\>\x00.*')
|
||||
retVal = ''
|
||||
data = self.sendCMD(['tmpd', 'quit'])
|
||||
if (data == None):
|
||||
|
@ -455,7 +401,7 @@ class DeviceManager:
|
|||
if localFile == '':
|
||||
localFile = os.path.join(self.tempRoot, "temp.txt")
|
||||
|
||||
promptre = re.compile('.*\$\>\x00.*')
|
||||
promptre = re.compile(self.prompt_regex + '.*')
|
||||
data = self.sendCMD(['cat ' + remoteFile, 'quit'], sleep = 5)
|
||||
if (data == None):
|
||||
return None
|
||||
|
@ -506,8 +452,7 @@ class DeviceManager:
|
|||
retVal = self.stripPrompt(data)
|
||||
if (retVal != None):
|
||||
retVal = retVal.strip('\n')
|
||||
if (self.debug >= 3):
|
||||
print "remote hash: '" + retVal + "'"
|
||||
if (self.debug >= 3): print "remote hash returned: '" + retVal + "'"
|
||||
return retVal
|
||||
|
||||
|
||||
|
@ -530,13 +475,14 @@ class DeviceManager:
|
|||
|
||||
file.close()
|
||||
hexval = mdsum.hexdigest()
|
||||
if (self.debug >= 3):
|
||||
print "local hash: '" + hexval + "'"
|
||||
if (self.debug >= 3): print "local hash returned: '" + hexval + "'"
|
||||
return hexval
|
||||
|
||||
# Gets the device root for the testing area on the device
|
||||
# For all devices we will use / type slashes and depend on the device-agent
|
||||
# to sort those out.
|
||||
# to sort those out. The agent will return us the device location where we
|
||||
# should store things, we will then create our /tests structure relative to
|
||||
# that returned path.
|
||||
# Structure on the device is as follows:
|
||||
# /tests
|
||||
# /<fennec>|<firefox> --> approot
|
||||
|
@ -546,11 +492,14 @@ class DeviceManager:
|
|||
# /mochitest
|
||||
def getDeviceRoot(self):
|
||||
if (not self.deviceRoot):
|
||||
if (self.dirExists('/tests')):
|
||||
self.deviceRoot = '/tests'
|
||||
else:
|
||||
self.mkDir('/tests')
|
||||
self.deviceRoot = '/tests'
|
||||
data = self.sendCMD(['testroot'], sleep = 1)
|
||||
if (data == None):
|
||||
return '/tests'
|
||||
self.deviceRoot = self.stripPrompt(data).strip('\n') + '/tests'
|
||||
|
||||
if (not self.dirExists(self.deviceRoot)):
|
||||
self.mkDir(self.deviceRoot)
|
||||
|
||||
return self.deviceRoot
|
||||
|
||||
# Either we will have /tests/fennec or /tests/firefox but we will never have
|
||||
|
@ -558,8 +507,10 @@ class DeviceManager:
|
|||
def getAppRoot(self):
|
||||
if (self.dirExists(self.getDeviceRoot() + '/fennec')):
|
||||
return self.getDeviceRoot() + '/fennec'
|
||||
else:
|
||||
elif (self.dirExists(self.getDeviceRoot() + '/firefox')):
|
||||
return self.getDeviceRoot() + '/firefox'
|
||||
else:
|
||||
return 'org.mozilla.fennec'
|
||||
|
||||
# Gets the directory location on the device for a specific test type
|
||||
# Type is one of: xpcshell|reftest|mochitest
|
||||
|
@ -592,8 +543,8 @@ class DeviceManager:
|
|||
dir = '/'.join(parts[:-1])
|
||||
elif self.fileExists('/' + filename):
|
||||
dir = '/' + filename
|
||||
elif self.fileExists('/tests/' + filename):
|
||||
dir = '/tests/' + filename
|
||||
elif self.fileExists(self.getDeviceRoot() + '/' + filename):
|
||||
dir = self.getDeviceRoot() + '/' + filename
|
||||
else:
|
||||
return None
|
||||
|
||||
|
@ -630,3 +581,71 @@ class DeviceManager:
|
|||
if (self.validateFile(remoteName, os.path.join(root, file)) <> True):
|
||||
return None
|
||||
return True
|
||||
|
||||
#TODO: make this simpler by doing a single directive at a time
|
||||
# Returns information about the device:
|
||||
# Directive indicates the information you want to get, your choices are:
|
||||
# os - name of the os
|
||||
# id - unique id of the device
|
||||
# uptime - uptime of the device
|
||||
# systime - system time of the device
|
||||
# screen - screen resolution
|
||||
# memory - memory stats
|
||||
# process - list of running processes (same as ps)
|
||||
# disk - total, free, available bytes on disk
|
||||
# power - power status (charge, battery temp)
|
||||
# all - all of them
|
||||
def getInfo(self, directive):
|
||||
data = None
|
||||
if (directive in ('os','id','uptime','systime','screen','memory','process',
|
||||
'disk','power')):
|
||||
data = self.sendCMD(['info ' + directive, 'quit'], sleep = 1)
|
||||
else:
|
||||
directive = None
|
||||
data = self.sendCMD(['info', 'quit'], sleep = 1)
|
||||
|
||||
if (data is None):
|
||||
return None
|
||||
|
||||
data = self.stripPrompt(data)
|
||||
result = {}
|
||||
|
||||
if directive:
|
||||
result[directive] = data.split('\n')
|
||||
for i in range(len(result[directive])):
|
||||
if (len(result[directive][i]) != 0):
|
||||
result[directive][i] = result[directive][i].strip()
|
||||
|
||||
# Get rid of any empty attributes
|
||||
result[directive].remove('')
|
||||
|
||||
else:
|
||||
lines = data.split('\n')
|
||||
result['id'] = lines[0]
|
||||
result['os'] = lines[1]
|
||||
result['systime'] = lines[2]
|
||||
result['uptime'] = lines[3]
|
||||
result['screen'] = lines[4]
|
||||
result['memory'] = lines[5]
|
||||
if (lines[6] == 'Power status'):
|
||||
tmp = []
|
||||
for i in range(4):
|
||||
tmp.append(line[7 + i])
|
||||
result['power'] = tmp
|
||||
tmp = []
|
||||
|
||||
# Linenum is the line where the process list begins
|
||||
linenum = 11
|
||||
for j in range(len(lines) - linenum):
|
||||
if (lines[j + linenum].strip() != ''):
|
||||
procline = lines[j + linenum].split('\t')
|
||||
|
||||
if len(procline) == 2:
|
||||
tmp.append([procline[0], procline[1]])
|
||||
elif len(procline) == 3:
|
||||
# Android has <userid> <procid> <procname>
|
||||
# We put the userid to achieve a common format
|
||||
tmp.append([procline[1], procline[2], procline[0]])
|
||||
result['process'] = tmp
|
||||
return result
|
||||
|
||||
|
|
|
@ -38,12 +38,15 @@
|
|||
import sys
|
||||
import os
|
||||
import time
|
||||
import socket
|
||||
import tempfile
|
||||
|
||||
sys.path.insert(0, os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0]))))
|
||||
|
||||
from automation import Automation
|
||||
from runtests import Mochitest
|
||||
from runtests import MochitestOptions
|
||||
from runtests import MochitestServer
|
||||
|
||||
import devicemanager
|
||||
|
||||
|
@ -61,7 +64,7 @@ class RemoteAutomation(Automation):
|
|||
def setProduct(self, productName):
|
||||
self._product = productName
|
||||
|
||||
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime):
|
||||
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo):
|
||||
status = proc.wait()
|
||||
print proc.stdout
|
||||
# todo: consider pulling log file from remote
|
||||
|
@ -74,7 +77,9 @@ class RemoteAutomation(Automation):
|
|||
args.remove('-foreground')
|
||||
except:
|
||||
pass
|
||||
return app, ['--environ:NO_EM_RESTART=1'] + args
|
||||
#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)
|
||||
|
@ -93,13 +98,13 @@ class RemoteAutomation(Automation):
|
|||
|
||||
# Setting timeout at 1 hour since on a remote device this takes much longer
|
||||
self.timeout = 3600
|
||||
time.sleep(5)
|
||||
time.sleep(15)
|
||||
|
||||
@property
|
||||
def pid(self):
|
||||
hexpid = self.dm.processExist(self.procName)
|
||||
if (hexpid == '' or hexpid == None):
|
||||
hexpid = 0
|
||||
hexpid = "0x0"
|
||||
return int(hexpid, 0)
|
||||
|
||||
@property
|
||||
|
@ -108,16 +113,17 @@ class RemoteAutomation(Automation):
|
|||
|
||||
def wait(self, timeout = None):
|
||||
timer = 0
|
||||
interval = 5
|
||||
|
||||
if timeout == None:
|
||||
timeout = self.timeout
|
||||
|
||||
while (self.dm.process.isAlive()):
|
||||
time.sleep(1)
|
||||
timer += 1
|
||||
while (self.dm.processExist(self.procName)):
|
||||
time.sleep(interval)
|
||||
timer += interval
|
||||
if (timer > timeout):
|
||||
break
|
||||
|
||||
|
||||
if (timer >= timeout):
|
||||
return 1
|
||||
return 0
|
||||
|
@ -140,16 +146,16 @@ class RemoteOptions(MochitestOptions):
|
|||
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",
|
||||
type = "string", dest = "remoteProductName",
|
||||
help = "The executable's name of remote product to test - either fennec or firefox, defaults to fennec.exe")
|
||||
defaults["remoteProductName"] = "fennec.exe"
|
||||
help = "The executable's name of remote product to test - either fennec or firefox, defaults to fennec")
|
||||
defaults["remoteProductName"] = "fennec"
|
||||
|
||||
self.add_option("--remote-logfile", action="store",
|
||||
type = "string", dest = "remoteLogFile",
|
||||
help = "Name of log file on the device. PLEASE ENSURE YOU HAVE CORRECT \ or / FOR THE PATH.")
|
||||
help = "Name of log file on the device relative to the device root. PLEASE ONLY USE A FILENAME.")
|
||||
defaults["remoteLogFile"] = None
|
||||
|
||||
self.add_option("--remote-webserver", action = "store",
|
||||
|
@ -167,53 +173,66 @@ class RemoteOptions(MochitestOptions):
|
|||
help = "ip address where the remote web server is hosted at")
|
||||
defaults["sslPort"] = automation.DEFAULT_SSL_PORT
|
||||
|
||||
defaults["remoteTestRoot"] = None
|
||||
defaults["logFile"] = "mochitest.log"
|
||||
if (automation._product == "fennec"):
|
||||
defaults["xrePath"] = "/tests/" + automation._product + "/xulrunner"
|
||||
else:
|
||||
defaults["xrePath"] = "/tests/" + automation._product
|
||||
defaults["utilityPath"] = "/tests/bin"
|
||||
defaults["certPath"] = "/tests/certs"
|
||||
defaults["autorun"] = True
|
||||
defaults["closeWhenDone"] = True
|
||||
defaults["testPath"] = ""
|
||||
defaults["app"] = "/tests/" + automation._product + "/" + defaults["remoteProductName"]
|
||||
defaults["app"] = None
|
||||
|
||||
self.set_defaults(**defaults)
|
||||
|
||||
def verifyRemoteOptions(self, options, automation):
|
||||
options.remoteTestRoot = automation._devicemanager.getDeviceRoot()
|
||||
|
||||
options.utilityPath = options.remoteTestRoot + "/bin"
|
||||
options.certPath = options.remoteTestRoot + "/certs"
|
||||
|
||||
if options.remoteWebServer == None and os.name != "nt":
|
||||
options.remoteWebServer = get_lan_ip()
|
||||
elif os.name == "nt":
|
||||
print "ERROR: you must specify a remoteWebServer ip address\n"
|
||||
return None
|
||||
|
||||
options.webServer = options.remoteWebServer
|
||||
|
||||
if (options.deviceIP == None):
|
||||
print "ERROR: you must provide a device IP"
|
||||
return None
|
||||
|
||||
if (options.remoteLogFile == None):
|
||||
options.remoteLogFile = automation._devicemanager.getDeviceRoot() + '/test.log'
|
||||
|
||||
# Set up our options that we depend on based on the above
|
||||
productRoot = options.remoteTestRoot + "/" + automation._product
|
||||
options.utilityPath = productRoot + "/bin"
|
||||
|
||||
# If provided, use cli value, otherwise reset as remoteTestRoot
|
||||
if (options.app == None):
|
||||
options.app = productRoot + "/" + options.remoteProductName
|
||||
|
||||
# Only reset the xrePath if it wasn't provided
|
||||
if (options.xrePath == None):
|
||||
if (automation._product == "fennec"):
|
||||
options.xrePath = productRoot + "/xulrunner"
|
||||
else:
|
||||
options.xrePath = options.utilityPath
|
||||
|
||||
return options
|
||||
|
||||
def verifyOptions(self, options, mochitest):
|
||||
# since we are reusing verifyOptions, it will exit if App is not found
|
||||
temp = options.app
|
||||
options.app = sys.argv[0]
|
||||
tempPort = options.httpPort
|
||||
tempSSL = options.sslPort
|
||||
tempIP = options.webServer
|
||||
options = MochitestOptions.verifyOptions(self, options, mochitest)
|
||||
options.webServer = tempIP
|
||||
options.app = temp
|
||||
options.sslPort = tempSSL
|
||||
options.httpPort = tempPort
|
||||
|
||||
if (options.remoteWebServer == None):
|
||||
print "ERROR: you must provide a remote webserver ip address"
|
||||
return None
|
||||
else:
|
||||
options.webServer = options.remoteWebServer
|
||||
|
||||
if (options.deviceIP == None):
|
||||
print "ERROR: you must provide a device IP"
|
||||
return None
|
||||
|
||||
if (options.remoteLogFile == None):
|
||||
print "ERROR: you must specify a remote log file and ensure you have the correct \ or / slashes"
|
||||
return None
|
||||
|
||||
# Set up our options that we depend on based on the above
|
||||
options.utilityPath = "/tests/" + mochitest._automation._product + "/bin"
|
||||
options.app = "/tests/" + mochitest._automation._product + "/" + options.remoteProductName
|
||||
if (mochitest._automation._product == "fennec"):
|
||||
options.xrePath = "/tests/" + mochitest._automation._product + "/xulrunner"
|
||||
else:
|
||||
options.xrePath = options.utilityPath
|
||||
|
||||
return options
|
||||
|
||||
class MochiRemote(Mochitest):
|
||||
|
@ -226,7 +245,7 @@ class MochiRemote(Mochitest):
|
|||
Mochitest.__init__(self, self._automation)
|
||||
self._dm = devmgr
|
||||
self.runSSLTunnel = False
|
||||
self.remoteProfile = "/tests/profile"
|
||||
self.remoteProfile = options.remoteTestRoot + "/profile"
|
||||
self.remoteLog = options.remoteLogFile
|
||||
|
||||
def cleanup(self, manifest, options):
|
||||
|
@ -234,11 +253,52 @@ class MochiRemote(Mochitest):
|
|||
self._dm.removeFile(self.remoteLog)
|
||||
self._dm.removeDir(self.remoteProfile)
|
||||
|
||||
def findPath(self, paths, filename = None):
|
||||
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
|
||||
|
||||
def startWebServer(self, options):
|
||||
pass
|
||||
|
||||
""" Create the webserver on the host and start it up """
|
||||
remoteXrePath = options.xrePath
|
||||
remoteProfilePath = options.profilePath
|
||||
remoteUtilityPath = options.utilityPath
|
||||
localAutomation = Automation()
|
||||
|
||||
paths = [options.xrePath, localAutomation.DIST_BIN, 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)
|
||||
sys.exit(1)
|
||||
paths.append("bin")
|
||||
paths.append(os.path.join("..", "bin"))
|
||||
|
||||
xpcshell = "xpcshell"
|
||||
if (os.name == "nt"):
|
||||
xpcshell += ".exe"
|
||||
|
||||
if (options.utilityPath):
|
||||
paths.insert(0, options.utilityPath)
|
||||
options.utilityPath = self.findPath(paths, xpcshell)
|
||||
if options.utilityPath == None:
|
||||
print "ERROR: unable to find utility path for %s, please specify with --utility-path" % (os.name)
|
||||
sys.exit(1)
|
||||
|
||||
options.profilePath = tempfile.mkdtemp()
|
||||
self.server = MochitestServer(localAutomation, options)
|
||||
self.server.start()
|
||||
|
||||
self.server.ensureReady(self.SERVER_STARTUP_TIMEOUT)
|
||||
options.xrePath = remoteXrePath
|
||||
options.utilityPath = remoteUtilityPath
|
||||
options.profilePath = remoteProfilePath
|
||||
|
||||
def stopWebServer(self, options):
|
||||
pass
|
||||
self.server.stop()
|
||||
|
||||
def runExtensionRegistration(self, options, browserEnv):
|
||||
pass
|
||||
|
@ -260,7 +320,10 @@ class MochiRemote(Mochitest):
|
|||
return retVal
|
||||
|
||||
def installChromeFile(self, filename, options):
|
||||
path = '/'.join(options.app.split('/')[:-1])
|
||||
parts = options.app.split('/')
|
||||
if (parts[0] == options.app):
|
||||
return "NO_CHROME_ON_DROID"
|
||||
path = '/'.join(parts[:-1])
|
||||
manifest = path + "/chrome/" + os.path.basename(filename)
|
||||
if self._dm.pushFile(filename, manifest) == None:
|
||||
raise devicemanager.FileError("Unable to install Chrome files on device.")
|
||||
|
@ -269,6 +332,33 @@ class MochiRemote(Mochitest):
|
|||
def getLogFilePath(self, logFile):
|
||||
return logFile
|
||||
|
||||
#
|
||||
# utilities to get the local ip address
|
||||
#
|
||||
if os.name != "nt":
|
||||
import fcntl
|
||||
import struct
|
||||
def get_interface_ip(ifname):
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
return socket.inet_ntoa(fcntl.ioctl(
|
||||
s.fileno(),
|
||||
0x8915, # SIOCGIFADDR
|
||||
struct.pack('256s', ifname[:15])
|
||||
)[20:24])
|
||||
|
||||
def get_lan_ip():
|
||||
ip = socket.gethostbyname(socket.gethostname())
|
||||
if ip.startswith("127.") and os.name != "nt":
|
||||
interfaces = ["eth0","eth1","eth2","wlan0","wlan1","wifi0","ath0","ath1","ppp0"]
|
||||
for ifname in interfaces:
|
||||
try:
|
||||
ip = get_interface_ip(ifname)
|
||||
break;
|
||||
except IOError:
|
||||
pass
|
||||
return ip
|
||||
|
||||
|
||||
def main():
|
||||
scriptdir = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
|
||||
dm = devicemanager.DeviceManager(None, None)
|
||||
|
@ -278,6 +368,10 @@ def main():
|
|||
|
||||
dm = devicemanager.DeviceManager(options.deviceIP, options.devicePort)
|
||||
auto.setDeviceManager(dm)
|
||||
options = parser.verifyRemoteOptions(options, auto)
|
||||
if (options == None):
|
||||
print "ERROR: Invalid options specified, use --help for a list of valid options"
|
||||
sys.exit(1)
|
||||
|
||||
productPieces = options.remoteProductName.split('.')
|
||||
if (productPieces != None):
|
||||
|
|
Загрузка…
Ссылка в новой задаче