Bug 877733 - bump mozinfo, mozprocess, mozdevice, mozinstall version and mirror to m-c;r=jmaher
authorJeff Hammel <jhammel@mozilla.com>
Mon, 17 Jun 2013 13:23:38 -0700
changeset 146849 1fae83d70978705b7fcc62ced1302c69df52b106
parent 146848 bb0567fbb4cce547f892669c0cbb1f2b933a8314
child 146850 a535b327054fac1bd2ff5384c2db0af3e5d31217
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmaher
bugs877733
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 877733 - bump mozinfo, mozprocess, mozdevice, mozinstall version and mirror to m-c;r=jmaher
testing/mozbase/generate_diff.py
testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py
testing/mozbase/mozdevice/mozdevice/dmcli.py
testing/mozbase/mozdevice/setup.py
testing/mozbase/mozdevice/sut_tests/dmunit.py
testing/mozbase/mozdevice/sut_tests/runtests.py
testing/mozbase/mozdevice/tests/sut.py
testing/mozbase/mozdevice/tests/sut_basic.py
testing/mozbase/mozinfo/README.md
testing/mozbase/mozinfo/mozinfo/__init__.py
testing/mozbase/mozinfo/mozinfo/mozinfo.py
testing/mozbase/mozinfo/setup.py
testing/mozbase/mozinstall/README.md
testing/mozbase/mozinstall/setup.py
testing/mozbase/mozprocess/setup.py
testing/mozbase/mozprocess/tests/iniparser/Makefile
testing/mozbase/mozprocess/tests/manifest.ini
--- a/testing/mozbase/generate_diff.py
+++ b/testing/mozbase/generate_diff.py
@@ -142,17 +142,19 @@ def parse_versions(*args):
             directory, version = arg.split('=', 1)
         else:
             directory = arg
             version = None
         retval.append((directory, version))
     return retval
 
 def version_tag(directory, version):
-    return '%s-%s' % (directory, version)
+    """return a version tag string given the directory name of the package"""
+    package = current_package_info[directory]['name']
+    return '%s-%s' % (package, version)
 
 def setup(**kwargs):
     """monkey-patch function for setuptools.setup"""
     assert current_package
     current_package_info[current_package] = kwargs
 
 def checkout_tag(src, directory, version):
     """
@@ -316,17 +318,17 @@ def main(args=sys.argv[1:]):
                             versions[index] = (directory, version)
                             print "Using %s=%s" % (directory, version)
                             break
                     else:
                         error("Cannot find PACKAGE_VERSION in %s" % setup_py)
 
             tag = version_tag(directory, version)
             if tag not in _tags:
-                error("Tag for '%s' -- %s -- not in tags")
+                error("Tag for '%s' -- %s -- not in tags:\n%s" % (directory, version, '\n'.join(sorted(_tags))))
 
         # ensure that the versions to mirror are compatible with what is in m-c
         old_package_info = current_package_info.copy()
         setuptools = sys.modules.get('setuptools')
         sys.modules['setuptools'] = sys.modules[__name__]
         try:
             for directory, version in versions:
 
@@ -371,15 +373,16 @@ def main(args=sys.argv[1:]):
             f.write(stdout)
             f.close()
 
         # ensure that the diff you just wrote isn't deleted
         untracked.append(os.path.abspath(output))
 
     finally:
         # cleanup
-        revert(hg_root, untracked)
+        if options.check:
+            revert(hg_root, untracked)
         shutil.rmtree(tempdir)
 
     print "Diff at %s" % output
 
 if __name__ == '__main__':
     main()
--- a/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
+++ b/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
@@ -166,16 +166,18 @@ class DeviceManagerADB(DeviceManager):
         # 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
         retryLimit = retryLimit or self.retryLimit
         if self.dirExists(destname):
             raise DMError("Attempted to push a file (%s) to a directory (%s)!" %
                           (localname, destname))
+        if not os.access(localname, os.F_OK):
+            raise DMError("File not found: %s" % localname)
 
         if self._useRunAs:
             remoteTmpFile = self.getTempDir() + "/" + os.path.basename(localname)
             self._checkCmd(["push", os.path.realpath(localname), remoteTmpFile],
                     retryLimit=retryLimit)
             self.shellCheckOutput(["dd", "if=" + remoteTmpFile, "of=" + destname])
             self.shellCheckOutput(["rm", remoteTmpFile])
         else:
@@ -228,18 +230,19 @@ class DeviceManagerADB(DeviceManager):
             res = data[0]
             if "Not a directory" in res or "No such file or directory" in res:
                 return False
         return True
 
     def fileExists(self, filepath):
         p = self._runCmd(["shell", "ls", "-a", filepath])
         data = p.stdout.readlines()
-        if (len(data) == 1):
-            if (data[0].rstrip() == filepath):
+        if len(data) == 1:
+            foundpath = data[0].decode('utf-8').rstrip()
+            if foundpath == filepath:
                 return True
         return False
 
     def removeFile(self, filename):
         if self.fileExists(filename):
             self._runCmd(["shell", "rm", filename])
 
     def removeDir(self, remoteDir):
--- a/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py
+++ b/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py
@@ -491,16 +491,19 @@ class DeviceManagerSUT(DeviceManager):
         own output will be flushed elsewhere.
 
         DEPRECATED: Use shell() or launchApplication() for new code
         """
         if not cmd:
             self._logger.warn("launchProcess called without command to run")
             return None
 
+        if cmd[0] == 'am' and hasattr(self, '_getExtraAmStartArgs'):
+            cmd = cmd[:2] + self._getExtraAmStartArgs() + cmd[2:] 
+
         cmdline = subprocess.list2cmdline(cmd)
         if (outputFile == "process.txt" or outputFile == None):
             outputFile = self.getDeviceRoot();
             if outputFile is None:
                 return None
             outputFile += "/process.txt"
             cmdline += " > " + outputFile
 
--- a/testing/mozbase/mozdevice/mozdevice/dmcli.py
+++ b/testing/mozbase/mozdevice/mozdevice/dmcli.py
@@ -45,17 +45,19 @@ class DMCli(object):
                                               { 'name': 'remote_file' }
                                               ],
                                     'help': 'copy file/dir to device' },
                           'pull': { 'function': self.pull,
                                     'args': [ { 'name': 'local_file' },
                                               { 'name': 'remote_file', 'nargs': '?' } ],
                                     'help': 'copy file/dir from device' },
                           'shell': { 'function': self.shell,
-                                    'args': [ { 'name': 'command', 'nargs': argparse.REMAINDER } ],
+                                    'args': [ { 'name': 'command', 'nargs': argparse.REMAINDER },
+                                              { 'name': '--root', 'action': 'store_true',
+                                                'help': 'Run command as root' }],
                                     'help': 'run shell command on device' },
                           'info': { 'function': self.getinfo,
                                     'args': [ { 'name': 'directive', 'nargs': '?' } ],
                                     'help': 'get information on specified '
                                     'aspect of the device (if no argument '
                                     'given, print all available information)'
                                     },
                           'ps': { 'function': self.processlist,
@@ -102,17 +104,18 @@ class DMCli(object):
                                       'help': 'check whether a file exists on the device'
                                    },
                           'launchfennec': { 'function': self.launchfennec,
                                             'args': [ { 'name': 'appname' },
                                                       { 'name': '--intent', 'action': 'store',
                                                         'default': 'android.intent.action.VIEW' },
                                                       { 'name': '--url', 'action': 'store' },
                                                       { 'name': '--extra-args', 'action': 'store' },
-                                                      { 'name': '--mozenv', 'action': 'store' },
+                                                      { 'name': '--mozenv', 'action': 'store',
+                                                        'help': 'Gecko environment variables to set in "KEY1=VAL1 KEY2=VAL2" format' },
                                                       { 'name': '--no-fail-if-running',
                                                         'action': 'store_true',
                                                         'help': 'Don\'t fail if application is already running' }
                                                       ],
                                             'help': 'launch fennec'
                                             },
                           'getip': { 'function': self.getip,
                                      'args': [ { 'name': 'interface', 'nargs': '*' } ],
@@ -244,19 +247,19 @@ class DMCli(object):
         self.dm.launchApplication(args.appname, args.activity_name,
                                   args.intent, url=args.url,
                                   failIfRunning=(not args.no_fail_if_running))
 
     def kill(self, args):
         for name in args.process_name:
             self.dm.killProcess(name)
 
-    def shell(self, args, root=False):
+    def shell(self, args):
         buf = StringIO.StringIO()
-        self.dm.shell(args.command, buf, root=root)
+        self.dm.shell(args.command, buf, root=args.root)
         print str(buf.getvalue()[0:-1]).rstrip()
 
     def getinfo(self, args):
         info = self.dm.getInfo(directive=args.directive)
         for (infokey, infoitem) in sorted(info.iteritems()):
             if infokey == "process":
                 pass # skip process list: get that through ps
             elif not args.directive and not infoitem:
@@ -316,18 +319,25 @@ class DMCli(object):
     def isfile(self, args):
         if self.dm.fileExists(args.remote_file):
             print "TRUE"
             return
         print "FALSE"
         return errno.ENOENT
 
     def launchfennec(self, args):
+        mozEnv = None
+        if args.mozenv:
+            mozEnv = {}
+            keyvals = args.mozenv.split()
+            for keyval in keyvals:
+                (key, _, val) = keyval.partition("=")
+                mozEnv[key] = val
         self.dm.launchFennec(args.appname, intent=args.intent,
-                             mozEnv=args.mozenv,
+                             mozEnv=mozEnv,
                              extraArgs=args.extra_args, url=args.url,
                              failIfRunning=(not args.no_fail_if_running))
 
     def getip(self, args):
         if args.interface:
             print(self.dm.getIP(args.interface))
         else:
             print(self.dm.getIP())
--- a/testing/mozbase/mozdevice/setup.py
+++ b/testing/mozbase/mozdevice/setup.py
@@ -1,15 +1,15 @@
 # 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/.
 
 from setuptools import setup
 
-PACKAGE_VERSION = '0.25'
+PACKAGE_VERSION = '0.26'
 
 setup(name='mozdevice',
       version=PACKAGE_VERSION,
       description="Mozilla-authored device management",
       long_description="see http://mozbase.readthedocs.org/",
       classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
       keywords='',
       author='Mozilla Automation and Testing Team',
--- a/testing/mozbase/mozdevice/sut_tests/dmunit.py
+++ b/testing/mozbase/mozdevice/sut_tests/dmunit.py
@@ -1,37 +1,41 @@
 # 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 types
+import unittest
+
+import mozlog
+
 from mozdevice import devicemanager
 from mozdevice import devicemanagerSUT
-import types
-import unittest
 
 ip = ''
 port = 0
 heartbeat_port = 0
-
+log_level = mozlog.ERROR
 
 class DeviceManagerTestCase(unittest.TestCase):
     """DeviceManager tests should subclass this.
     """
 
     """Set to False in your derived class if this test
     should not be run on the Python agent.
     """
     runs_on_test_device = True
 
     def _setUp(self):
         """ Override this if you want set-up code in your test."""
         return
 
     def setUp(self):
-        self.dm = devicemanagerSUT.DeviceManagerSUT(host=ip, port=port)
+        self.dm = devicemanagerSUT.DeviceManagerSUT(host=ip, port=port,
+                                                    logLevel=log_level)
         self.dmerror = devicemanager.DMError
         self.nettools = devicemanager.NetworkTools
         self._setUp()
 
 
 class DeviceManagerTestLoader(unittest.TestLoader):
 
     def __init__(self, isTestDevice=False):
--- a/testing/mozbase/mozdevice/sut_tests/runtests.py
+++ b/testing/mozbase/mozdevice/sut_tests/runtests.py
@@ -1,29 +1,30 @@
 # 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/.
 
 from optparse import OptionParser
 import os
 import re
+import sys
 import unittest
-import sys
+
+import mozlog
 
 import dmunit
 import genfiles
 
 
 def main(ip, port, heartbeat_port, scripts, directory, isTestDevice, verbose):
     dmunit.ip = ip
     dmunit.port = port
     dmunit.heartbeat_port = heartbeat_port
     if verbose:
-        from mozdevice.devicemanagerSUT import DeviceManagerSUT
-        DeviceManagerSUT.debug = 4
+        dmunit.log_level = mozlog.DEBUG
 
     suite = unittest.TestSuite()
 
     genfiles.gen_test_files()
 
     if scripts:
         # Ensure the user didn't include the .py on the name of the test file
         # (and get rid of it if they did)
--- a/testing/mozbase/mozdevice/tests/sut.py
+++ b/testing/mozbase/mozdevice/tests/sut.py
@@ -21,38 +21,49 @@ class MockAgent(object):
         self._sock.bind(("127.0.0.1", 0))
         self._sock.listen(1)
 
         self.tester = tester
 
         self.thread = Thread(target=self._serve_thread)
         self.thread.start()
 
+        self.should_stop = False
+
     @property
     def port(self):
         return self._sock.getsockname()[1]
 
     def _serve_thread(self):
         conn = None
         while self.commands:
             if not conn:
                 conn, addr = self._sock.accept()
                 conn.send("$>\x00")
             (command, response) = self.commands.pop(0)
             data = conn.recv(1024).strip()
             self.tester.assertEqual(data, command)
             # send response and prompt separately to test for bug 789496
             # FIXME: Improve the mock agent, since overloading the meaning
             # of 'response' is getting confusing.
-            if response is None:
+            if response is None: # code for "shut down"
                 conn.shutdown(socket.SHUT_RDWR)
                 conn.close()
                 conn = None
-            elif type(response) is int:
-                time.sleep(response)
+            elif type(response) is int: # code for "time out"
+                max_timeout = 15.0
+                timeout = 0.0
+                interval = 0.1
+                while not self.should_stop and timeout < max_timeout:
+                    time.sleep(interval)
+                    timeout += interval
+                if timeout >= max_timeout:
+                    raise Exception("Maximum timeout reached! This should not "
+                                    "happen")
+                return
             else:
                 # pull is handled specially, as we just pass back the full
                 # command line
                 if "pull" in command:
                     conn.send(response)
                 else:
                     conn.send("%s\n" % response)
                 conn.send("$>\x00")
--- a/testing/mozbase/mozdevice/tests/sut_basic.py
+++ b/testing/mozbase/mozdevice/tests/sut_basic.py
@@ -45,16 +45,17 @@ class BasicTest(unittest.TestCase):
         d = mozdevice.DroidSUT("127.0.0.1", port=a.port, logLevel=mozlog.DEBUG)
         d.default_timeout = 1
         exceptionThrown = False
         try:
             d.removeFile('/mnt/sdcard/tests/test.txt')
         except mozdevice.DMError:
             exceptionThrown = True
         self.assertEqual(exceptionThrown, True)
+        a.should_stop = True
         a.wait()
 
     def test_shell(self):
         """Tests shell command"""
         for cmd in [ ("exec foobar", False), ("execsu foobar", True) ]:
             for retcode in [ 1, 2 ]:
                 a = MockAgent(self, commands=[(cmd[0],
                                                "\nreturn code [%s]" % retcode)])
deleted file mode 100644
--- a/testing/mozbase/mozinfo/README.md
+++ /dev/null
@@ -1,62 +0,0 @@
-Throughout [mozmill](https://developer.mozilla.org/en/Mozmill)
-and other Mozilla python code, checking the underlying
-platform is done in many different ways.  The various checks needed
-lead to a lot of copy+pasting, leaving the reader to wonder....is this
-specific check necessary for (e.g.) an operating system?  Because
-information is not consolidated, checks are not done consistently, nor
-is it defined what we are checking for.
-
-[MozInfo](https://github.com/mozilla/mozbase/tree/master/mozinfo)
-proposes to solve this problem.  MozInfo is a bridge interface,
-making the underlying (complex) plethora of OS and architecture
-combinations conform to a subset of values of relavence to 
-Mozilla software. The current implementation exposes relavent key,
-values: `os`, `version`, `bits`, and `processor`.  Additionally, the
-service pack in use is available on the windows platform.
-
-
-# API Usage
-
-MozInfo is a python package.  Downloading the software and running
-`python setup.py develop` will allow you to do `import mozinfo`
-from python.  
-[mozinfo.py](https://github.com/mozilla/mozbase/blob/master/mozinfo/mozinfo.py)
-is the only file contained is this package,
-so if you need a single-file solution, you can just download or call
-this file through the web.
-
-The top level attributes (`os`, `version`, `bits`, `processor`) are
-available as module globals:
-
-    if mozinfo.os == 'win': ...
-
-In addition, mozinfo exports a dictionary, `mozinfo.info`, that
-contain these values.  mozinfo also exports:
-
-- `choices`: a dictionary of possible values for os, bits, and
-  processor
-- `main`: the console_script entry point for mozinfo
-- `unknown`: a singleton denoting a value that cannot be determined
-
-`unknown` has the string representation `"UNKNOWN"`. unknown will evaluate
-as `False` in python:
-
-    if not mozinfo.os: ... # unknown!
-
-
-# Command Line Usage
-
-MozInfo comes with a command line, `mozinfo` which may be used to
-diagnose one's current system.
-
-Example output:
-
-    os: linux
-    version: Ubuntu 10.10
-    bits: 32
-    processor: x86
-
-Three of these fields, os, bits, and processor, have a finite set of
-choices.  You may display the value of these choices using 
-`mozinfo --os`, `mozinfo --bits`, and `mozinfo --processor`. 
-`mozinfo --help` documents command-line usage.
--- a/testing/mozbase/mozinfo/mozinfo/__init__.py
+++ b/testing/mozbase/mozinfo/mozinfo/__init__.py
@@ -1,5 +1,54 @@
 # 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/.
 
+"""
+interface to transform introspected system information to a format palatable to
+Mozilla
+
+Module variables:
+
+.. attribute:: bits
+
+   32 or 64
+
+.. attribute:: isBsd
+
+   Returns ``True`` if the operating system is BSD
+
+.. attribute:: isLinux
+
+   Returns ``True`` if the operating system is Linux
+
+.. attribute:: isMac
+
+   Returns ``True`` if the operating system is Mac
+
+.. attribute:: isWin
+
+   Returns ``True`` if the operating system is Windows
+
+.. attribute:: os
+
+   Operating system [``'win'``, ``'mac'``, ``'linux'``, ...]
+
+.. attribute:: processor
+
+   Processor architecture [``'x86'``, ``'x86_64'``, ``'ppc'``, ...]
+
+.. attribute:: version
+
+   Operating system version string. For windows, the service pack information is also included
+
+.. attribute:: info
+
+   Returns information identifying the current system.
+
+   * :attr:`bits`
+   * :attr:`os`
+   * :attr:`processor`
+   * :attr:`version`
+
+"""
+
 from mozinfo import *
--- a/testing/mozbase/mozinfo/mozinfo/mozinfo.py
+++ b/testing/mozbase/mozinfo/mozinfo/mozinfo.py
@@ -1,36 +1,30 @@
 #!/usr/bin/env python
 
 # 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/.
 
-"""
-file for interface to transform introspected system information to a format
-pallatable to Mozilla
-
-Information:
-- os : what operating system ['win', 'mac', 'linux', ...]
-- bits : 32 or 64
-- processor : processor architecture ['x86', 'x86_64', 'ppc', ...]
-- version : operating system version string
-
-For windows, the service pack information is also included
-"""
-
 # TODO: it might be a good idea of adding a system name (e.g. 'Ubuntu' for
 # linux) to the information; I certainly wouldn't want anyone parsing this
 # information and having behaviour depend on it
 
 import os
 import platform
 import re
 import sys
 
+try:
+    import json
+except ImportError:
+    import simplejson as json
+
+import mozfile
+
 # keep a copy of the os module since updating globals overrides this
 _os = os
 
 class unknown(object):
     """marker class for unknown information"""
     def __nonzero__(self):
         return False
     def __str__(self):
@@ -53,17 +47,20 @@ if system in ["Microsoft", "Windows"]:
     if "PROCESSOR_ARCHITEW6432" in os.environ:
         processor = os.environ.get("PROCESSOR_ARCHITEW6432", processor)
     else:
         processor = os.environ.get('PROCESSOR_ARCHITECTURE', processor)
         system = os.environ.get("OS", system).replace('_', ' ')
         service_pack = os.sys.getwindowsversion()[4]
         info['service_pack'] = service_pack
 elif system == "Linux":
-    (distro, version, codename) = platform.dist()
+    if hasattr(platform, "linux_distribution"):
+        (distro, version, codename) = platform.linux_distribution()
+    else:
+        (distro, version, codename) = platform.dist()
     version = "%s %s" % (distro, version)
     if not processor:
         processor = machine
     info['os'] = 'linux'
 elif system in ['DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD']:
     info['os'] = 'bsd'
     version = sys.platform
 elif system == "Darwin":
@@ -106,17 +103,25 @@ def sanitize(info):
             info["processor"] = "x86_64"
             info["bits"] = 64
         else:
             info["processor"] = "x86"
             info["bits"] = 32
 
 # method for updating information
 def update(new_info):
-    """update the info"""
+    """Update the info.
+    new_info can either be a dict or a path/url
+    to a json file containing a dict."""
+
+    if isinstance(new_info, basestring):
+        f = mozfile.load(new_info)
+        new_info = json.loads(f.read())
+        f.close()
+
     info.update(new_info)
     sanitize(info)
     globals().update(info)
 
     # convenience data for os access
     for os_name in choices['os']:
         globals()['is' + os_name.title()] = info['os'] == os_name
     # unix is special
@@ -139,31 +144,22 @@ def main(args=None):
     for key in choices:
         parser.add_option('--%s' % key, dest=key,
                           action='store_true', default=False,
                           help="display choices for %s" % key)
     options, args = parser.parse_args()
 
     # args are JSON blobs to override info
     if args:
-        try:
-            from json import loads
-        except ImportError:
-            try:
-                from simplejson import loads
-            except ImportError:
-                def loads(string):
-                    """*really* simple json; will not work with unicode"""
-                    return eval(string, {'true': True, 'false': False, 'null': None})
         for arg in args:
             if _os.path.exists(arg):
                 string = file(arg).read()
             else:
                 string = arg
-            update(loads(string))
+            update(json.loads(string))
 
     # print out choices if requested
     flag = False
     for key, value in options.__dict__.items():
         if value is True:
             print '%s choices: %s' % (key, ' '.join([str(choice)
                                                      for choice in choices[key]]))
             flag = True
--- a/testing/mozbase/mozinfo/setup.py
+++ b/testing/mozbase/mozinfo/setup.py
@@ -1,36 +1,27 @@
 # 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.4'
-
-# get documentation from the README
-try:
-    here = os.path.dirname(os.path.abspath(__file__))
-    description = file(os.path.join(here, 'README.md')).read()
-except (OSError, IOError):
-    description = ''
+PACKAGE_VERSION = '0.5'
 
 # dependencies
-deps = []
+deps = ['mozfile >= 0.6']
 try:
     import json
 except ImportError:
     deps = ['simplejson']
 
 setup(name='mozinfo',
       version=PACKAGE_VERSION,
-      description="file for interface to transform introspected system information to a format pallatable to Mozilla",
-      long_description=description,
+      description="Library to get system information for use in Mozilla testing",
+      long_description="see http://mozbase.readthedocs.org",
       classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
       keywords='mozilla',
       author='Mozilla Automation and Testing Team',
       author_email='tools@lists.mozilla.org',
       url='https://wiki.mozilla.org/Auto-tools/Projects/MozBase',
       license='MPL',
       packages=['mozinfo'],
       include_package_data=True,
deleted file mode 100644
--- a/testing/mozbase/mozinstall/README.md
+++ /dev/null
@@ -1,60 +0,0 @@
-[Mozinstall](https://github.com/mozilla/mozbase/tree/master/mozinstall) is a
-python package for installing and uninstalling Mozilla applications on
-various platforms.
-
-For example, depending on the platform, Firefox can be distributed as a
-zip, tar.bz2, exe, or dmg file or cloned from a repository. Mozinstall takes
-the hassle out of extracting and/or running these files and for convenience
-returns the full path to the install directory. In the case that mozinstall
-is invoked from the command line, the binary path will be printed to stdout.
-
-To remove an installed application the uninstaller can be used. It requires
-the installation path of the application and will remove all the installed
-files. On Windows the uninstaller will be tried first.
-
-# Usage
-Mozinstall can be used as API or via the CLI commands.
-
-## API
-An application can be installed by running the commands below. The install
-method will return the installation path of the application.
-
-    import mozinstall
-    path = mozinstall.install(%installer%, %install_folder%)
-
-To retrieve the real binary call get_binary with the path and
-the application name as arguments:
-
-    mozinstall.get_binary(path, 'firefox')
-
-If the application is not needed anymore the uninstaller will remove all
-traces from the system:
-
-    mozinstall.uninstall(path)
-
-## CLI
-The installer can also be used as a command line tool:
-
-    $ mozinstall -d firefox %installer%
-
-Whereby the directory option is optional and will default to the current
-working directory. If the installation was successful the path to the
-binary will be printed to stdout.
-
-Also the uninstaller can be called via the command line:
-
-    $ mozuninstall %install_path%
-
-# Error Handling
-
-Mozinstall throws different types of exceptions:
-
-- mozinstall.InstallError is thrown when the installation fails for any reason. A traceback is provided.
-- mozinstall.InvalidBinary is thrown when the binary cannot be found.
-- mozinstall.InvalidSource is thrown when the source is not a recognized file type (zip, exe, tar.bz2, tar.gz, dmg).
-
-
-# Dependencies
-
-Mozinstall depends on the [mozinfo](https://github.com/mozilla/mozbase/tree/master/mozinfo) 
-package which is also found in the mozbase repository.
--- a/testing/mozbase/mozinstall/setup.py
+++ b/testing/mozbase/mozinstall/setup.py
@@ -6,27 +6,26 @@ import os
 from setuptools import setup
 
 try:
     here = os.path.dirname(os.path.abspath(__file__))
     description = file(os.path.join(here, 'README.md')).read()
 except IOError:
     description = None
 
-PACKAGE_VERSION = '1.4'
+PACKAGE_VERSION = '1.6'
 
-deps = ['mozinfo == 0.4',
+deps = ['mozinfo >= 0.4',
         'mozfile'
        ]
 
 setup(name='mozInstall',
       version=PACKAGE_VERSION,
-      description="This is a utility package for installing and uninstalling "
-                  "Mozilla applications on various platforms.",
-      long_description=description,
+      description="package for installing and uninstalling Mozilla applications",
+      long_description="see http://mozbase.readthedocs.org/",
       # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
       classifiers=['Environment :: Console',
                    'Intended Audience :: Developers',
                    'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)',
                    'Natural Language :: English',
                    'Operating System :: OS Independent',
                    'Programming Language :: Python',
                    'Topic :: Software Development :: Libraries :: Python Modules',
@@ -35,15 +34,19 @@ setup(name='mozInstall',
       author='Mozilla Automation and Tools team',
       author_email='tools@lists.mozilla.org',
       url='https://wiki.mozilla.org/Auto-tools/Projects/MozBase',
       license='MPL 2.0',
       packages=['mozinstall'],
       include_package_data=True,
       zip_safe=False,
       install_requires=deps,
+      # we have to generate two more executables for those systems that cannot run as Administrator
+      # and the filename containing "install" triggers the UAC
       entry_points="""
       # -*- Entry points: -*-
       [console_scripts]
       mozinstall = mozinstall:install_cli
       mozuninstall = mozinstall:uninstall_cli
+      moz_add_to_system = mozinstall:install_cli
+      moz_remove_from_system = mozinstall:uninstall_cli
       """,
       )
--- a/testing/mozbase/mozprocess/setup.py
+++ b/testing/mozbase/mozprocess/setup.py
@@ -1,15 +1,15 @@
 # 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/.
 
 from setuptools import setup
 
-PACKAGE_VERSION = '0.10'
+PACKAGE_VERSION = '0.11'
 
 setup(name='mozprocess',
       version=PACKAGE_VERSION,
       description="Mozilla-authored process handling",
       long_description='see http://mozbase.readthedocs.org/',
       classifiers=['Environment :: Console',
                    'Intended Audience :: Developers',
                    'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)',
--- a/testing/mozbase/mozprocess/tests/iniparser/Makefile
+++ b/testing/mozbase/mozprocess/tests/iniparser/Makefile
@@ -22,17 +22,17 @@ ifeq ($(UNAME), Linux)
 endif
 ifeq ($(UNAME), Darwin)
     # Compiler settings
     CC      = gcc
     # Ar settings to build the library
     AR	    = ar
     ARFLAGS = rcv
     SHLD = libtool
-    CFLAGS  = -v -arch i386 -isysroot /Developer/SDKs/MacOSX10.6.sdk -fPIC -Wall -ansi -pedantic
+    CFLAGS  = -v -arch i386 -fPIC -Wall -ansi -pedantic
     LDFLAGS = -arch_only i386
 endif
 ifeq ($(WIN32), 1)
     CC = cl
     CFLAGS = //Od //D "_WIN32" //D "WIN32" //D "_CONSOLE" //D "_CRT_SECURE_NO_WARNINGS" //D "_UNICODE" //D "UNICODE" //Gm //EHsc //RTC1 //MDd //W3 //nologo //c //ZI //TC
     LDFLAGS = //OUT:"iniparser.lib" //NOLOGO
     LINK = lib
     RM = rm -f
--- a/testing/mozbase/mozprocess/tests/manifest.ini
+++ b/testing/mozbase/mozprocess/tests/manifest.ini
@@ -1,5 +1,5 @@
 # does not currently work on windows
 # see https://bugzilla.mozilla.org/show_bug.cgi?id=790765#c51
 
 [test_mozprocess.py]
-skip-if = os == 'win'
\ No newline at end of file
+disabled = bug 877864