Bug 778329 Fix and improve DeviceManagerSUT.unpackFile(). r=mcote

--HG--
extra : rebase_source : 7354a74a68538da45e515476e3fe49f50a50b562
This commit is contained in:
Mihnea Dobrescu-Balaur 2012-08-01 11:50:05 -04:00
parent 223f04555a
commit 3e13f9d15d
2 changed files with 68 additions and 100 deletions

View File

@ -55,7 +55,7 @@ class DeviceManager:
success: True
failure: False
"""
@abstractmethod
def mkDir(self, name):
"""
@ -64,7 +64,7 @@ class DeviceManager:
success: directory name
failure: None
"""
def mkDirs(self, filename):
"""
make directory structure on the device
@ -85,7 +85,7 @@ class DeviceManager:
print "failed making directory: " + str(name)
return None
return name
@abstractmethod
def pushDir(self, localDir, remoteDir):
"""
@ -104,7 +104,7 @@ class DeviceManager:
success: True
failure: False
"""
@abstractmethod
def fileExists(self, filepath):
"""
@ -115,7 +115,7 @@ class DeviceManager:
success: True
failure: False
"""
@abstractmethod
def listFiles(self, rootdir):
"""
@ -125,7 +125,7 @@ class DeviceManager:
success: array of filenames, ['file1', 'file2', ...]
failure: None
"""
@abstractmethod
def removeFile(self, filename):
"""
@ -134,7 +134,7 @@ class DeviceManager:
success: output of telnet, i.e. "removing file: /mnt/sdcard/tests/test.txt"
failure: None
"""
@abstractmethod
def removeDir(self, remoteDir):
"""
@ -144,7 +144,7 @@ class DeviceManager:
success: output of telnet, i.e. "removing file: /mnt/sdcard/tests/test.txt"
failure: None
"""
@abstractmethod
def getProcessList(self):
"""
@ -182,7 +182,7 @@ class DeviceManager:
success: pid
failure: None
"""
pid = None
#filter out extra spaces
@ -194,7 +194,7 @@ class DeviceManager:
parts = appname.split('"')
if (len(parts) > 2):
appname = ' '.join(parts[2:]).strip()
pieces = appname.split(' ')
parts = pieces[0].split('/')
app = parts[-1]
@ -202,7 +202,7 @@ class DeviceManager:
procList = self.getProcessList()
if (procList == []):
return None
for proc in procList:
procName = proc[1].split('/')[-1]
if (procName == app):
@ -219,7 +219,7 @@ class DeviceManager:
success: True
failure: False
"""
@abstractmethod
def catFile(self, remoteFile):
"""
@ -228,7 +228,7 @@ class DeviceManager:
success: filecontents
failure: None
"""
@abstractmethod
def pullFile(self, remoteFile):
"""
@ -237,7 +237,7 @@ class DeviceManager:
success: output of pullfile, string
failure: None
"""
@abstractmethod
def getFile(self, remoteFile, localFile = ''):
"""
@ -247,7 +247,7 @@ class DeviceManager:
success: output of pullfile, string
failure: None
"""
@abstractmethod
def getDirectory(self, remoteDir, localDir, checkDir=True):
"""
@ -260,7 +260,7 @@ class DeviceManager:
success: list of files, string
failure: None
"""
@abstractmethod
def isDir(self, remotePath):
"""
@ -270,7 +270,7 @@ class DeviceManager:
failure: False
Throws a FileError exception when null (invalid dir/filename)
"""
@abstractmethod
def validateFile(self, remoteFile, localFile):
"""
@ -280,7 +280,7 @@ class DeviceManager:
success: True
failure: False
"""
@abstractmethod
def getRemoteHash(self, filename):
"""
@ -290,7 +290,7 @@ class DeviceManager:
success: MD5 hash for given filename
failure: None
"""
def getLocalHash(self, filename):
"""
return the md5 sum of a file on the host
@ -299,7 +299,7 @@ class DeviceManager:
success: MD5 hash for given filename
failure: None
"""
file = open(filename, 'rb')
if (file == None):
return None
@ -362,7 +362,7 @@ class DeviceManager:
success: path for test root
failure: None
"""
devroot = self.getDeviceRoot()
if (devroot == None):
return None
@ -381,24 +381,24 @@ class DeviceManager:
For Example: SIGINT and SIGDFL to process x
"""
#currently not implemented in device agent - todo
pass
def getReturnCode(self, processID):
"""Get a return code from process ending -- needs support on device-agent"""
# TODO: make this real
return 0
@abstractmethod
def unpackFile(self, filename):
def unpackFile(self, file_path, dest_dir=None):
"""
external function
returns:
success: output of unzip command
failure: None
"""
@abstractmethod
def reboot(self, ipAddr=None, port=30000):
"""
@ -407,7 +407,7 @@ class DeviceManager:
success: status from test agent
failure: None
"""
def validateDir(self, localDir, remoteDir):
"""
validate localDir from host to remoteDir on the device
@ -416,7 +416,7 @@ class DeviceManager:
success: True
failure: False
"""
if (self.debug >= 2): print "validating directory: " + localDir + " to " + remoteDir
for root, dirs, files in os.walk(localDir):
parts = root.split(localDir)
@ -428,7 +428,7 @@ class DeviceManager:
if (self.validateFile(remoteName, os.path.join(root, file)) <> True):
return False
return True
@abstractmethod
def getInfo(self, directive=None):
"""
@ -448,7 +448,7 @@ class DeviceManager:
success: dict of info strings by directive name
failure: None
"""
@abstractmethod
def installApp(self, appBundlePath, destPath=None):
"""
@ -466,7 +466,7 @@ class DeviceManager:
success: True
failure: None
"""
@abstractmethod
def updateApp(self, appBundlePath, processName=None,
destPath=None, ipAddr=None, port=30000):
@ -476,7 +476,7 @@ class DeviceManager:
success: text status from command or callback server
failure: None
"""
@abstractmethod
def getCurrentTime(self):
"""
@ -491,7 +491,7 @@ class DeviceManager:
external function
returns:
success: file is created in <testroot>/logcat.log
failure:
failure:
"""
#TODO: spawn this off in a separate thread/process so we can collect all the logcat information
@ -590,14 +590,14 @@ class NetworkTools:
connected = True
s.close()
break
except:
except:
if seed > maxportnum:
print "Could not find open port after checking 5000 ports"
raise
seed += 1
except:
print "Socket error trying to find open port"
return seed
def _pop_last_line(file):

View File

@ -9,6 +9,7 @@ import time, datetime
import os
import re
import hashlib
import posixpath
import subprocess
from threading import Thread
import traceback
@ -30,7 +31,7 @@ class AgentError(Exception):
class DeviceManagerSUT(DeviceManager):
host = ''
port = 0
debug = 2
debug = 2
retries = 0
tempRoot = os.getcwd()
base_prompt = '$>'
@ -309,7 +310,7 @@ class DeviceManagerSUT(DeviceManager):
return False
if (self.debug >= 3): print "sending: push " + destname
filesize = os.path.getsize(localname)
f = open(localname, 'rb')
data = f.read()
@ -321,7 +322,7 @@ class DeviceManagerSUT(DeviceManager):
except AgentError, e:
print "error pushing file: %s" % e.msg
return False
if (self.debug >= 3): print "push returned: " + str(retVal)
validated = False
@ -345,7 +346,7 @@ class DeviceManagerSUT(DeviceManager):
else:
if (self.debug >= 2): print "Push File Failed to Validate!"
return False
# external function
# returns:
# success: directory name
@ -449,7 +450,7 @@ class DeviceManagerSUT(DeviceManager):
return None
return retVal
# does a recursive delete of directory on the device: rm -Rf remoteDir
# external function
# returns:
@ -481,7 +482,7 @@ class DeviceManagerSUT(DeviceManager):
files += [[pidproc[0], pidproc[1]]]
elif (len(pidproc) == 3):
#android returns <userID> <procID> <procName>
files += [[pidproc[1], pidproc[2], pidproc[0]]]
files += [[pidproc[1], pidproc[2], pidproc[0]]]
return files
# external function
@ -500,7 +501,7 @@ class DeviceManagerSUT(DeviceManager):
print "WARNING: process %s appears to be running already\n" % appname
if (failIfRunning):
return None
try:
data = self.runCmds([{ 'cmd': 'exec ' + appname }])
except AgentError:
@ -535,8 +536,8 @@ class DeviceManagerSUT(DeviceManager):
return None
outputFile += "/process.txt"
cmdline += " > " + outputFile
# Prepend our env to the command
# Prepend our env to the command
cmdline = '%s %s' % (self.formatEnvString(env), cmdline)
if self.fireProcess(cmdline, failIfRunning) is None:
@ -593,17 +594,17 @@ class DeviceManagerSUT(DeviceManager):
confused if the prompt string exists within the file being catted.
However it means we can't use the response-handling logic in sendCMD().
"""
def err(error_msg):
err_str = 'error returned from pull: %s' % error_msg
print err_str
self._sock = None
raise FileError(err_str)
raise FileError(err_str)
# FIXME: We could possibly move these socket-reading functions up to
# the class level if we wanted to refactor sendCMD(). For now they are
# only used to pull files.
def uread(to_recv, error_msg):
""" unbuffered read """
try:
@ -638,7 +639,7 @@ class DeviceManagerSUT(DeviceManager):
prompt = self.base_prompt + self.prompt_sep
buffer = ''
# expected return value:
# <filename>,<filesize>\n<filedata>
# or, if error,
@ -693,12 +694,12 @@ class DeviceManagerSUT(DeviceManager):
def getFile(self, remoteFile, localFile = ''):
if localFile == '':
localFile = os.path.join(self.tempRoot, "temp.txt")
try:
retVal = self.pullFile(remoteFile)
except:
return None
if (retVal is None):
return None
@ -727,7 +728,7 @@ class DeviceManagerSUT(DeviceManager):
return None
if not is_dir:
return None
filelist = self.listFiles(remoteDir)
if (self.debug >= 3): print filelist
if not os.path.exists(localDir):
@ -753,7 +754,7 @@ class DeviceManagerSUT(DeviceManager):
# FIXME: This should be improved so we know when a file transfer really
# failed.
if self.getFile(remotePath, localPath) == None:
print 'failed to get file "%s"; continuing anyway...' % remotePath
print 'failed to get file "%s"; continuing anyway...' % remotePath
return filelist
# external function
@ -767,7 +768,7 @@ class DeviceManagerSUT(DeviceManager):
except AgentError:
# normally there should be no error here; a nonexistent file/directory will
# return the string "<filename>: No such file or directory".
# However, I've seen AGENT-WARNING returned before.
# However, I've seen AGENT-WARNING returned before.
return False
retVal = data.strip()
@ -791,7 +792,7 @@ class DeviceManagerSUT(DeviceManager):
return True
return False
# return the md5 sum of a remote file
# internal function
# returns:
@ -808,7 +809,7 @@ class DeviceManagerSUT(DeviceManager):
retVal = data.strip()
if (self.debug >= 3): print "remote hash returned: '" + retVal + "'"
return retVal
# 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. The agent will return us the device location where we
@ -856,25 +857,20 @@ class DeviceManagerSUT(DeviceManager):
# returns:
# success: output of unzip command
# failure: None
def unpackFile(self, filename):
def unpackFile(self, file_path, dest_dir=None):
devroot = self.getDeviceRoot()
if (devroot == None):
return None
dir = ''
parts = filename.split('/')
if (len(parts) > 1):
if self.fileExists(filename):
dir = '/'.join(parts[:-1])
elif self.fileExists('/' + filename):
dir = '/' + filename
elif self.fileExists(devroot + '/' + filename):
dir = devroot + '/' + filename
else:
return None
# if no dest_dir is passed in just set it to file_path's folder
if not dest_dir:
dest_dir = posixpath.dirname(file_path)
if dest_dir[-1] != '/':
dest_dir += '/'
try:
data = self.runCmds([{ 'cmd': 'cd ' + dir }, { 'cmd': 'unzp ' + filename }])
data = self.runCmds([{ 'cmd': 'unzp %s %s' % (file_path, dest_dir)}])
except AgentError:
return None
@ -885,10 +881,10 @@ class DeviceManagerSUT(DeviceManager):
# success: status from test agent
# failure: None
def reboot(self, ipAddr=None, port=30000):
cmd = 'rebt'
cmd = 'rebt'
if (self.debug > 3): print "INFO: sending rebt command"
callbacksvrstatus = None
callbacksvrstatus = None
if (ipAddr is not None):
#create update.info file:
@ -952,7 +948,7 @@ class DeviceManagerSUT(DeviceManager):
# Get rid of any 0 length members of the arrays
for k, v in result.iteritems():
result[k] = filter(lambda x: x != '', result[k])
# Format the process output
if 'process' in result:
proclist = []
@ -1082,34 +1078,6 @@ class DeviceManagerSUT(DeviceManager):
And ports starting at 30000.
NOTE: the detection for current IP address only works on Linux!
"""
# external function
# returns:
# success: output of unzip command
# failure: None
def unpackFile(self, filename):
devroot = self.getDeviceRoot()
if (devroot == None):
return None
dir = ''
parts = filename.split('/')
if (len(parts) > 1):
if self.fileExists(filename):
dir = '/'.join(parts[:-1])
elif self.fileExists('/' + filename):
dir = '/' + filename
elif self.fileExists(devroot + '/' + filename):
dir = devroot + '/' + filename
else:
return None
try:
data = self.runCmds(['cd ' + dir, 'unzp ' + filename])
except AgentError:
return None
return data
def getCallbackIpAndPort(self, aIp, aPort):
ip = aIp
nettools = NetworkTools()
@ -1209,7 +1177,7 @@ class callbackServer():
self.debug = debuglevel
if (self.debug >= 3): print "Creating server with " + str(ip) + ":" + str(port)
self.server = myServer((ip, port), self.myhandler)
self.server_thread = Thread(target=self.server.serve_forever)
self.server_thread = Thread(target=self.server.serve_forever)
self.server_thread.setDaemon(True)
self.server_thread.start()
@ -1242,4 +1210,4 @@ class callbackServer():
gCallbackData = self.request.recv(1024)
#print "Callback Handler got data: " + str(gCallbackData)
self.request.send("OK")