Bug 772105 - Give a better error if failed to push a file with devicemanagerSUT;r=jmaher

This commit is contained in:
William Lachance 2012-07-11 10:24:05 -04:00
parent 8c73d3a4e7
commit 8590954360

View File

@ -35,7 +35,7 @@ class DeviceManagerSUT(DeviceManager):
base_prompt_re = '\$\>'
prompt_sep = '\x00'
prompt_regex = '.*(' + base_prompt_re + prompt_sep + ')'
agentErrorRE = re.compile('^##AGENT-WARNING##.*')
agentErrorRE = re.compile('^##AGENT-WARNING##\ ?(.*)')
# TODO: member variable to indicate error conditions.
# This should be set to a standard error from the errno module.
@ -55,15 +55,11 @@ class DeviceManagerSUT(DeviceManager):
def _cmdNeedsResponse(self, cmd):
""" Not all commands need a response from the agent:
* if the cmd matches the pushRE then it is the first half of push
and therefore we want to wait until the second half before looking
for a response
* rebt obviously doesn't get a response
* uninstall performs a reboot to ensure starting in a clean state and
so also doesn't look for a response
"""
noResponseCmds = [re.compile('^push .*$'),
re.compile('^rebt'),
noResponseCmds = [re.compile('^rebt'),
re.compile('^uninst .*$'),
re.compile('^pull .*$')]
@ -119,7 +115,7 @@ class DeviceManagerSUT(DeviceManager):
return False
def sendCmds(self, cmdlist, outputfile, timeout = None, newline = True):
def sendCmds(self, cmdlist, outputfile, timeout = None):
'''
a wrapper for _doCmds that loops up to self.retrylimit iterations.
this allows us to move the retry logic outside of the _doCmds() to make it
@ -131,7 +127,7 @@ class DeviceManagerSUT(DeviceManager):
done = False
while self.retries < self.retrylimit:
try:
self._doCmds(cmdlist, outputfile, timeout, newline)
self._doCmds(cmdlist, outputfile, timeout)
return
except AgentError, err:
# re-raise error if it's fatal (i.e. the device got the command but
@ -144,18 +140,18 @@ class DeviceManagerSUT(DeviceManager):
raise AgentError("unable to connect to %s after %s attempts" % (self.host, self.retrylimit))
def runCmds(self, cmdlist, timeout = None, newline = True):
def runCmds(self, cmdlist, timeout = None):
'''
similar to sendCmds, but just returns any output as a string instead of
writing to a file. this is normally what you want to call to send a set
of commands to the agent
'''
outputfile = StringIO.StringIO()
self.sendCmds(cmdlist, outputfile, timeout, newline)
self.sendCmds(cmdlist, outputfile, timeout)
outputfile.seek(0)
return outputfile.read()
def _doCmds(self, cmdlist, outputfile, timeout, newline):
def _doCmds(self, cmdlist, outputfile, timeout):
promptre = re.compile(self.prompt_regex + '$')
shouldCloseSocket = False
recvGuard = 1000
@ -178,26 +174,32 @@ class DeviceManagerSUT(DeviceManager):
raise AgentError("unable to connect socket: "+str(msg))
for cmd in cmdlist:
if newline: cmd += '\r\n'
cmdline = '%s\r\n' % cmd['cmd']
try:
numbytes = self._sock.send(cmd)
if (numbytes != len(cmd)):
raise AgentError("ERROR: our cmd was %s bytes and we only sent %s" % (len(cmd),
numbytes))
if (self.debug >= 4): print "send cmd: " + str(cmd)
sent = self._sock.send(cmdline)
if sent != len(cmdline):
raise AgentError("ERROR: our cmd was %s bytes and we "
"only sent %s" % (len(cmdline), sent))
if cmd.get('data'):
sent = self._sock.send(cmd['data'])
if sent != len(cmd['data']):
raise AgentError("ERROR: we had %s bytes of data to send, but "
"only sent %s" % (len(cmd['data'], sent)))
if (self.debug >= 4): print "sent cmd: " + str(cmd['cmd'])
except socket.error, msg:
self._sock.close()
self._sock = None
if self.debug >= 1:
print "Error sending data to socket. cmd="+str(cmd)+"; err="+str(msg)
print "Error sending data to socket. cmd="+str(cmd['cmd'])+"; err="+str(msg)
return False
# Check if the command should close the socket
shouldCloseSocket = self._shouldCmdCloseSocket(cmd)
shouldCloseSocket = self._shouldCmdCloseSocket(cmd['cmd'])
# Handle responses from commands
if (self._cmdNeedsResponse(cmd)):
if (self._cmdNeedsResponse(cmd['cmd'])):
found = False
loopguard = 0
data = ""
@ -213,14 +215,16 @@ class DeviceManagerSUT(DeviceManager):
except socket.error, msg:
self._sock.close()
self._sock = None
raise AgentError("Error receiving data from socket. cmd="+str(cmd)+"; err="+str(msg))
raise AgentError("Error receiving data from socket. cmd="+str(cmd['cmd'])+"; err="+str(msg))
data += temp
# If something goes wrong in the agent it will send back a string that
# starts with '##AGENT-ERROR##'
if self.agentErrorRE.match(data):
raise AgentError("Agent Error processing command: %s" % cmd, fatal=True)
# starts with '##AGENT-WARNING##'
errorMatch = self.agentErrorRE.match(data)
if errorMatch:
raise AgentError("Agent Error processing command '%s'; err='%s'" %
(cmd['cmd'], errorMatch.group(1)), fatal=True)
for line in data.splitlines():
if promptre.match(line):
@ -261,9 +265,9 @@ class DeviceManagerSUT(DeviceManager):
try:
if cwd:
self.sendCmds(['execcwd %s %s' % (cwd, cmdline)], outputfile)
self.sendCmds([{ 'cmd': 'execcwd %s %s' % (cwd, cmdline) }], outputfile)
else:
self.sendCmds(['exec su -c "%s"' % cmdline], outputfile)
self.sendCmds([{ 'cmd': 'exec su -c "%s"' % cmdline }], outputfile)
except AgentError:
return None
@ -306,9 +310,11 @@ class DeviceManagerSUT(DeviceManager):
f.close()
try:
retVal = self.runCmds(['push ' + destname + ' ' + str(filesize) + '\r\n', data], newline = False)
except AgentError:
retVal = False
retVal = self.runCmds([{ 'cmd': 'push ' + destname + ' ' + str(filesize),
'data': data }])
except AgentError, e:
print "error pushing file: %s" % e.msg
return False
if (self.debug >= 3): print "push returned: " + str(retVal)
@ -343,7 +349,7 @@ class DeviceManagerSUT(DeviceManager):
return name
else:
try:
retVal = self.runCmds(['mkdr ' + name])
retVal = self.runCmds([{ 'cmd': 'mkdr ' + name }])
except AgentError:
retVal = None
return retVal
@ -396,7 +402,7 @@ class DeviceManagerSUT(DeviceManager):
match = ".*" + dirname.replace('^', '\^') + "$"
dirre = re.compile(match)
try:
data = self.runCmds(['cd ' + dirname, 'cwd'])
data = self.runCmds([ { 'cmd': 'cd ' + dirname }, { 'cmd': 'cwd' }])
except AgentError:
return False
@ -432,7 +438,7 @@ class DeviceManagerSUT(DeviceManager):
if (self.dirExists(rootdir) == False):
return []
try:
data = self.runCmds(['cd ' + rootdir, 'ls'])
data = self.runCmds([{ 'cmd': 'cd ' + rootdir }, { 'cmd': 'ls' }])
except AgentError:
return []
@ -449,7 +455,7 @@ class DeviceManagerSUT(DeviceManager):
def removeFile(self, filename):
if (self.debug>= 2): print "removing file: " + filename
try:
retVal = self.runCmds(['rm ' + filename])
retVal = self.runCmds([{ 'cmd': 'rm ' + filename }])
except AgentError:
return None
@ -462,7 +468,7 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def removeDir(self, remoteDir):
try:
retVal = self.runCmds(['rmdr ' + remoteDir])
retVal = self.runCmds([{ 'cmd': 'rmdr ' + remoteDir }])
except AgentError:
return None
@ -474,7 +480,7 @@ class DeviceManagerSUT(DeviceManager):
# failure: []
def getProcessList(self):
try:
data = self.runCmds(['ps'])
data = self.runCmds([{ 'cmd': 'ps' }])
except AgentError:
return []
@ -507,7 +513,7 @@ class DeviceManagerSUT(DeviceManager):
return None
try:
data = self.runCmds(['exec ' + appname])
data = self.runCmds([{ 'cmd': 'exec ' + appname }])
except AgentError:
return None
@ -556,7 +562,7 @@ class DeviceManagerSUT(DeviceManager):
if forceKill:
print "WARNING: killProcess(): forceKill parameter unsupported on SUT"
try:
data = self.runCmds(['kill ' + appname])
data = self.runCmds([{ 'cmd': 'kill ' + appname }])
except AgentError:
return False
@ -568,7 +574,7 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getTempDir(self):
try:
data = self.runCmds(['tmpd'])
data = self.runCmds([{ 'cmd': 'tmpd' }])
except AgentError:
return None
@ -580,7 +586,7 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def catFile(self, remoteFile):
try:
data = self.runCmds(['cat ' + remoteFile])
data = self.runCmds([{ 'cmd': 'cat ' + remoteFile }])
except AgentError:
return None
@ -649,7 +655,7 @@ class DeviceManagerSUT(DeviceManager):
# or, if error,
# <filename>,-1\n<error message>
try:
data = self.runCmds(['pull ' + remoteFile])
data = self.runCmds([{ 'cmd': 'pull ' + remoteFile }])
except AgentError:
return None
@ -768,7 +774,7 @@ class DeviceManagerSUT(DeviceManager):
# Throws a FileError exception when null (invalid dir/filename)
def isDir(self, remotePath):
try:
data = self.runCmds(['isdir ' + remotePath])
data = self.runCmds([{ 'cmd': 'isdir ' + remotePath }])
except AgentError:
# normally there should be no error here; a nonexistent file/directory will
# return the string "<filename>: No such file or directory".
@ -804,7 +810,7 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getRemoteHash(self, filename):
try:
data = self.runCmds(['hash ' + filename])
data = self.runCmds([{ 'cmd': 'hash ' + filename }])
except AgentError:
return None
@ -833,7 +839,7 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getDeviceRoot(self):
try:
data = self.runCmds(['testroot'])
data = self.runCmds([{ 'cmd': 'testroot' }])
except:
return None
@ -847,7 +853,7 @@ class DeviceManagerSUT(DeviceManager):
def getAppRoot(self, packageName):
try:
data = self.runCmds(['getapproot '+packageName])
data = self.runCmds([{ 'cmd': 'getapproot '+packageName }])
except:
return None
@ -875,7 +881,7 @@ class DeviceManagerSUT(DeviceManager):
return None
try:
data = self.runCmds(['cd ' + dir, 'unzp ' + filename])
data = self.runCmds([{ 'cmd': 'cd ' + dir }, { 'cmd': 'unzp ' + filename }])
except AgentError:
return None
@ -896,7 +902,8 @@ class DeviceManagerSUT(DeviceManager):
try:
destname = '/data/data/com.mozilla.SUTAgentAndroid/files/update.info'
data = "%s,%s\rrebooting\r" % (ipAddr, port)
self.runCmds(['push ' + destname + ' ' + str(len(data)) + '\r\n', data], newline = False)
self.runCmds([{ 'cmd': 'push %s %s' % (destname, len(data)),
'data': data }])
except AgentError:
return None
@ -906,7 +913,7 @@ class DeviceManagerSUT(DeviceManager):
callbacksvr = callbackServer(ip, port, self.debug)
try:
status = self.runCmds([cmd])
status = self.runCmds([{ 'cmd': cmd }])
except AgentError:
return None
@ -943,7 +950,7 @@ class DeviceManagerSUT(DeviceManager):
directives = [directive]
for d in directives:
data = self.runCmds(['info ' + d])
data = self.runCmds([{ 'cmd': 'info ' + d }])
if (data is None):
continue
data = collapseSpaces.sub(' ', data)
@ -980,7 +987,7 @@ class DeviceManagerSUT(DeviceManager):
if destPath:
cmd += ' ' + destPath
try:
data = self.runCmds([cmd])
data = self.runCmds([{ 'cmd': cmd }])
except AgentError:
return None
@ -1006,7 +1013,7 @@ class DeviceManagerSUT(DeviceManager):
if installPath:
cmd += ' ' + installPath
try:
data = self.runCmds([cmd])
data = self.runCmds([{ 'cmd': cmd }])
except AgentError:
return None
@ -1051,7 +1058,7 @@ class DeviceManagerSUT(DeviceManager):
if (self.debug >= 3): print "INFO: updateApp using command: " + str(cmd)
try:
status = self.runCmds([cmd])
status = self.runCmds([{ 'cmd': cmd }])
except AgentError:
return None
@ -1071,7 +1078,7 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getCurrentTime(self):
try:
data = self.runCmds(['clok'])
data = self.runCmds([{ 'cmd': 'clok' }])
except AgentError:
return None
@ -1175,8 +1182,8 @@ class DeviceManagerSUT(DeviceManager):
if (self.debug >= 3): print "INFO: adjusting screen resolution to %s, %s and rebooting" % (width, height)
try:
self.runCmds(["exec setprop persist.tegra.dpy%s.mode.width %s" % (screentype, width)])
self.runCmds(["exec setprop persist.tegra.dpy%s.mode.height %s" % (screentype, height)])
self.runCmds([{ 'cmd': "exec setprop persist.tegra.dpy%s.mode.width %s" % (screentype, width) }])
self.runCmds([{ 'cmd': "exec setprop persist.tegra.dpy%s.mode.height %s" % (screentype, height) }])
except AgentError:
return False
@ -1188,7 +1195,7 @@ class DeviceManagerSUT(DeviceManager):
# failure: False
def chmodDir(self, remoteDir):
try:
self.runCmds(["chmod "+remoteDir])
self.runCmds([{ 'cmd': "chmod "+remoteDir }])
except AgentError:
return False
return True