Bug 802242 - mirror mozbase -> m-c for week of Oct 16 @ https://github.com/mozilla/mozbase/commit/aa50f7cf0f67b5762277bbafe5eecdd65440ed4b ; r=wlach
authorJeff Hammel <jhammel@mozilla.com>
Wed, 17 Oct 2012 09:44:50 -0700
changeset 110701 c654454d60e13cf191a2af45a152473f29930d72
parent 110700 b21bafeb5b50c4c8f2d7502ef80e796458d253a7
child 110702 414f6660e1189b68fae6c53b5e002355efa05908
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewerswlach
bugs802242
milestone19.0a1
Bug 802242 - mirror mozbase -> m-c for week of Oct 16 @ https://github.com/mozilla/mozbase/commit/aa50f7cf0f67b5762277bbafe5eecdd65440ed4b ; r=wlach
testing/mozbase/mozdevice/mozdevice/Zeroconf.py
testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
testing/mozbase/mozdevice/mozdevice/dmcli.py
testing/mozbase/mozdevice/setup.py
testing/mozbase/mozprocess/mozprocess/processhandler.py
testing/mozbase/mozprocess/setup.py
testing/mozbase/mozrunner/setup.py
testing/mozbase/setup_development.py
old mode 100644
new mode 100755
--- a/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
+++ b/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
@@ -155,34 +155,34 @@ class DeviceManagerADB(DeviceManager):
 
     def _disconnectRemoteADB(self):
         self._checkCmd(["disconnect", self.host + ":" + str(self.port)])
 
     def pushFile(self, localname, destname):
         """
         Copies localname from the host to destname on the device
         """
-        try:
-            if (os.name == "nt"):
-                destname = destname.replace('\\', '/')
-            if (self.useRunAs):
-                remoteTmpFile = self.getTempDir() + "/" + os.path.basename(localname)
-                self._checkCmd(["push", os.path.realpath(localname), remoteTmpFile])
-                if self.useDDCopy:
-                    self._checkCmdAs(["shell", "dd", "if=" + remoteTmpFile, "of=" + destname])
-                else:
-                    self._checkCmdAs(["shell", "cp", remoteTmpFile, destname])
-                self._checkCmd(["shell", "rm", remoteTmpFile])
+        # you might expect us to put the file *in* the directory in this case,
+        # but that would be different behaviour from devicemanagerSUT. Throw
+        # an exception so we have the same behaviour between the two
+        # implementations
+        if self.dirExists(destname):
+            raise DMError("Attempted to push a file (%s) to a directory (%s)!" %
+                          (localname, destname))
+
+        if self.useRunAs:
+            remoteTmpFile = self.getTempDir() + "/" + os.path.basename(localname)
+            self._checkCmd(["push", os.path.realpath(localname), remoteTmpFile])
+            if self.useDDCopy:
+                self.shellCheckOutput(["dd", "if=" + remoteTmpFile, "of=" + destname])
             else:
-                self._checkCmd(["push", os.path.realpath(localname), destname])
-            if (self.dirExists(destname)):
-                destname = destname + "/" + os.path.basename(localname)
-            return True
-        except:
-            raise DMError("Error pushing file to device")
+                self.shellCheckOutput(["cp", remoteTmpFile, destname])
+            self.shellCheckOutput(["rm", remoteTmpFile])
+        else:
+            self._checkCmd(["push", os.path.realpath(localname), destname])
 
     def mkDir(self, name):
         """
         Creates a single directory on the device file system
         """
         result = self._runCmdAs(["shell", "mkdir", name]).stdout.read()
         if 'read-only file system' in result.lower():
             raise DMError("Error creating directory: read only file system")
@@ -190,50 +190,49 @@ class DeviceManagerADB(DeviceManager):
     def pushDir(self, localDir, remoteDir):
         """
         Push localDir from host to remoteDir on the device
         """
         # adb "push" accepts a directory as an argument, but if the directory
         # contains symbolic links, the links are pushed, rather than the linked
         # files; we either zip/unzip or push file-by-file to get around this
         # limitation
-        if (not self.dirExists(remoteDir)):
+        if not self.dirExists(remoteDir):
             self.mkDirs(remoteDir+"/x")
-            if (self.useZip):
-                try:
-                    localZip = tempfile.mktemp()+".zip"
-                    remoteZip = remoteDir + "/adbdmtmp.zip"
-                    subprocess.check_output(["zip", "-r", localZip, '.'], cwd=localDir)
-                    self.pushFile(localZip, remoteZip)
-                    os.remove(localZip)
-                    data = self._runCmdAs(["shell", "unzip", "-o", remoteZip, "-d", remoteDir]).stdout.read()
-                    self._checkCmdAs(["shell", "rm", remoteZip])
-                    if (re.search("unzip: exiting", data) or re.search("Operation not permitted", data)):
-                        raise Exception("unzip failed, or permissions error")
-                except:
-                    print "zip/unzip failure: falling back to normal push"
-                    self.useZip = False
-                    self.pushDir(localDir, remoteDir)
-            else:
-                for root, dirs, files in os.walk(localDir, followlinks=True):
-                    relRoot = os.path.relpath(root, localDir)
-                    for f in files:
-                        localFile = os.path.join(root, f)
-                        remoteFile = remoteDir + "/"
-                        if (relRoot!="."):
-                            remoteFile = remoteFile + relRoot + "/"
-                        remoteFile = remoteFile + f
-                        self.pushFile(localFile, remoteFile)
-                    for d in dirs:
-                        targetDir = remoteDir + "/"
-                        if (relRoot!="."):
-                            targetDir = targetDir + relRoot + "/"
-                        targetDir = targetDir + d
-                        if (not self.dirExists(targetDir)):
-                            self.mkDir(targetDir)
+        if self.useZip:
+            try:
+                localZip = tempfile.mktemp() + ".zip"
+                remoteZip = remoteDir + "/adbdmtmp.zip"
+                subprocess.check_output(["zip", "-r", localZip, '.'], cwd=localDir)
+                self.pushFile(localZip, remoteZip)
+                os.remove(localZip)
+                data = self._runCmdAs(["shell", "unzip", "-o", remoteZip, "-d", remoteDir]).stdout.read()
+                self._checkCmdAs(["shell", "rm", remoteZip])
+                if re.search("unzip: exiting", data) or re.search("Operation not permitted", data):
+                    raise Exception("unzip failed, or permissions error")
+            except:
+                print "zip/unzip failure: falling back to normal push"
+                self.useZip = False
+                self.pushDir(localDir, remoteDir)
+        else:
+            for root, dirs, files in os.walk(localDir, followlinks=True):
+                relRoot = os.path.relpath(root, localDir)
+                for f in files:
+                    localFile = os.path.join(root, f)
+                    remoteFile = remoteDir + "/"
+                    if relRoot != ".":
+                        remoteFile = remoteFile + relRoot + "/"
+                    remoteFile = remoteFile + f
+                    self.pushFile(localFile, remoteFile)
+                for d in dirs:
+                    targetDir = remoteDir + "/"
+                    if relRoot != ".":
+                        targetDir = targetDir + relRoot + "/"
+                    targetDir = targetDir + d
+                    self.mkDir(targetDir)
 
     def dirExists(self, remotePath):
         """
         Return True if remotePath is an existing directory on the device.
         """
         p = self._runCmd(["shell", "ls", "-a", remotePath + '/'])
 
         data = p.stdout.readlines()
@@ -549,20 +548,19 @@ class DeviceManagerADB(DeviceManager):
     def getTempDir(self):
         """
         Return a temporary directory on the device
 
         Will also ensure that directory exists
         """
         # Cache result to speed up operations depending
         # on the temporary directory.
-        if self.tempDir == None:
+        if not self.tempDir:
             self.tempDir = self.getDeviceRoot() + "/tmp"
-            if (not self.dirExists(self.tempDir)):
-                return self.mkDir(self.tempDir)
+            self.mkDir(self.tempDir)
 
         return self.tempDir
 
     def getAppRoot(self, packageName):
         """
         Returns the app root directory
 
         E.g /tests/fennec or /tests/firefox
--- a/testing/mozbase/mozdevice/mozdevice/dmcli.py
+++ b/testing/mozbase/mozdevice/mozdevice/dmcli.py
@@ -125,49 +125,53 @@ class DMCli(object):
                                  host=self.options.host,
                                  port=self.options.port)
         command['function'](*command_args)
 
     def add_options(self, parser):
         parser.add_option("-v", "--verbose", action="store_true",
                           dest="verbose",
                           help="Verbose output from DeviceManager",
-                          default = False)
+                          default=False)
         parser.add_option("--host", action="store",
-                          type = "string", dest = "host",
-                          help = "Device hostname (only if using TCP/IP)",
+                          type="string", dest="host",
+                          help="Device hostname (only if using TCP/IP)",
                           default=os.environ.get('TEST_DEVICE'))
         parser.add_option("-p", "--port", action="store",
-                          type = "int", dest = "port",
-                          help = "Custom device port (if using SUTAgent or "
+                          type="int", dest="port",
+                          help="Custom device port (if using SUTAgent or "
                           "adb-over-tcp)", default=None)
         parser.add_option("-m", "--dmtype", action="store",
-                          type = "string", dest = "dmtype",
-                          help = "DeviceManager type (adb or sut, defaults " \
+                          type="string", dest="dmtype",
+                          help="DeviceManager type (adb or sut, defaults " \
                               "to adb)", default=os.environ.get('DM_TRANS',
                                                                 'adb'))
         parser.add_option("-d", "--hwid", action="store",
                           type="string", dest="hwid",
                           help="HWID", default=None)
+        parser.add_option("--package-name", action="store",
+                          type="string", dest="packagename",
+                          help="Packagename (if using DeviceManagerADB)",
+                          default=None)
 
     def getDevice(self, dmtype="adb", hwid=None, host=None, port=None):
         '''
         Returns a device with the specified parameters
         '''
         if self.options.verbose:
             mozdevice.DroidSUT.debug = 4
 
         if hwid:
             return mozdevice.DroidConnectByHWID(hwid)
 
         if dmtype == "adb":
             if host and not port:
                 port = 5555
-            return mozdevice.DroidADB(packageName=None, host=host,
-                                      port=port)
+            return mozdevice.DroidADB(packageName=self.options.packagename,
+                                      host=host, port=port)
         elif dmtype == "sut":
             if not host:
                 self.parser.error("Must specify host with SUT!")
             if not port:
                 port = 20701
             return mozdevice.DroidSUT(host=host, port=port)
         else:
             self.parser.error("Unknown device manager type: %s" % type)
--- a/testing/mozbase/mozdevice/setup.py
+++ b/testing/mozbase/mozdevice/setup.py
@@ -1,25 +1,25 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
 from setuptools import setup
 
-PACKAGE_VERSION = '0.11'
+PACKAGE_VERSION = '0.12'
 
 # take description from README
 here = os.path.dirname(os.path.abspath(__file__))
 try:
     description = file(os.path.join(here, 'README.md')).read()
 except (OSError, IOError):
     description = ''
 
-deps = ['mozprocess == 0.7']
+deps = ['mozprocess == 0.8']
 
 setup(name='mozdevice',
       version=PACKAGE_VERSION,
       description="Mozilla-authored device management",
       long_description=description,
       classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
       keywords='',
       author='Mozilla Automation and Testing Team',
--- a/testing/mozbase/mozprocess/mozprocess/processhandler.py
+++ b/testing/mozbase/mozprocess/mozprocess/processhandler.py
@@ -193,17 +193,17 @@ class ProcessHandlerMixin(object):
                     winprocess.EnvironmentBlock(env),
                     cwd, startupinfo)
                 self._child_created = True
                 self._handle = hp
                 self._thread = ht
                 self.pid = pid
                 self.tid = tid
 
-                if canCreateJob:
+                if not self._ignore_children and canCreateJob:
                     try:
                         # We create a new job for this process, so that we can kill
                         # the process and any sub-processes
                         # Create the IO Completion Port
                         self._io_port = winprocess.CreateIoCompletionPort()
                         self._job = winprocess.CreateJobObject()
 
                         # Now associate the io comp port and the job object
@@ -387,20 +387,21 @@ falling back to not using job objects fo
                 if self._handle:
                     self.returncode = winprocess.GetExitCodeProcess(self._handle)
                 else:
                     # Dude, the process is like totally dead!
                     return self.returncode
 
                 # Python 2.5 uses isAlive versus is_alive use the proper one
                 threadalive = False
-                if hasattr(self._procmgrthread, 'is_alive'):
-                    threadalive = self._procmgrthread.is_alive()
-                else:
-                    threadalive = self._procmgrthread.isAlive()
+                if hasattr(self, "_procmgrthread"):
+                    if hasattr(self._procmgrthread, 'is_alive'):
+                        threadalive = self._procmgrthread.is_alive()
+                    else:
+                        threadalive = self._procmgrthread.isAlive()
                 if self._job and threadalive: 
                     # Then we are managing with IO Completion Ports
                     # wait on a signal so we know when we have seen the last
                     # process come through.
                     # We use queues to synchronize between the thread and this
                     # function because events just didn't have robust enough error
                     # handling on pre-2.7 versions
                     err = None
@@ -421,17 +422,17 @@ falling back to not using job objects fo
                     if err is not None:
                         raise OSError(err)
 
 
                 else:
                     # Not managing with job objects, so all we can reasonably do
                     # is call waitforsingleobject and hope for the best
 
-                    if MOZPROCESS_DEBUG:
+                    if MOZPROCESS_DEBUG and not self._ignore_children:
                         print "DBG::MOZPROC NOT USING JOB OBJECTS!!!"
                     # First, make sure we have not already ended
                     if self.returncode != winprocess.STILL_ACTIVE:
                         self._cleanup()
                         return self.returncode
 
                     rc = None
                     if self._handle:
--- a/testing/mozbase/mozprocess/setup.py
+++ b/testing/mozbase/mozprocess/setup.py
@@ -1,16 +1,16 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
 from setuptools import setup
 
-PACKAGE_VERSION = '0.7'
+PACKAGE_VERSION = '0.8'
 
 # take description from README
 here = os.path.dirname(os.path.abspath(__file__))
 try:
     description = file(os.path.join(here, 'README.md')).read()
 except (OSError, IOError):
     description = ''
 
--- a/testing/mozbase/mozrunner/setup.py
+++ b/testing/mozbase/mozrunner/setup.py
@@ -2,28 +2,28 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
 import sys
 from setuptools import setup
 
 PACKAGE_NAME = "mozrunner"
-PACKAGE_VERSION = '5.13'
+PACKAGE_VERSION = '5.14'
 
 desc = """Reliable start/stop/configuration of Mozilla Applications (Firefox, Thunderbird, etc.)"""
 # take description from README
 here = os.path.dirname(os.path.abspath(__file__))
 try:
     description = file(os.path.join(here, 'README.md')).read()
 except (OSError, IOError):
     description = ''
 
 deps = ['mozinfo == 0.4',
-        'mozprocess == 0.7',
+        'mozprocess == 0.8',
         'mozprofile == 0.4',
        ]
 
 # we only support python 2 right now
 assert sys.version_info[0] == 2
 
 setup(name=PACKAGE_NAME,
       version=PACKAGE_VERSION,
--- a/testing/mozbase/setup_development.py
+++ b/testing/mozbase/setup_development.py
@@ -95,17 +95,17 @@ def dependency_info(dep):
     for joiner in ('==', '<=', '>='):
         if joiner in dep:
             retval['Type'] = joiner
             name, version = [i.strip() for i in dep.split(joiner, 1)]
             retval['Name'] = name
             retval['Version'] = version
             break
     else:
-        retval['name'] = dep.strip()
+        retval['Name'] = dep.strip()
     return retval
 
 def unroll_dependencies(dependencies):
     """
     unroll a set of dependencies to a flat list
 
     dependencies = {'packageA': set(['packageB', 'packageC', 'packageF']),
                     'packageB': set(['packageC', 'packageD', 'packageE', 'packageG']),