From 85909543608e0c8536282d7cd7c99f2a80490444 Mon Sep 17 00:00:00 2001 From: William Lachance Date: Wed, 11 Jul 2012 10:24:05 -0400 Subject: [PATCH] Bug 772105 - Give a better error if failed to push a file with devicemanagerSUT;r=jmaher --- build/mobile/devicemanagerSUT.py | 117 ++++++++++++++++--------------- 1 file changed, 62 insertions(+), 55 deletions(-) diff --git a/build/mobile/devicemanagerSUT.py b/build/mobile/devicemanagerSUT.py index d92d9e15e4a4..70d7b2b1b1c3 100644 --- a/build/mobile/devicemanagerSUT.py +++ b/build/mobile/devicemanagerSUT.py @@ -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, # ,-1\n 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 ": 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