Hello community,

here is the log from the commit of package python-salt-testing for 
openSUSE:Factory checked in at 2014-08-06 11:42:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-salt-testing (Old)
 and      /work/SRC/openSUSE:Factory/.python-salt-testing.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-salt-testing"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-salt-testing/python-salt-testing.changes  
2014-05-02 14:03:05.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-salt-testing.new/python-salt-testing.changes 
    2014-08-06 11:42:34.000000000 +0200
@@ -1,0 +2,11 @@
+Tue Aug  5 19:14:58 UTC 2014 - [email protected]
+
+- updated to 2014.8.5
+  + Added with_system_user, with_system_group and with_system_user_and_group 
which surpasses the functionality from the now deprecated with_system_account.
+  + Added expensiveTest decorator which is supposed to mark tests which cost 
money
+  + Allow passing a path to the docker binary
+  + Updated the PEP8 PyLint plugin to support some newly added messages
+  + Improved the string formatting pylint plugin
+  + Support mock_open as a fake object so that import errors are not triggered
+
+-------------------------------------------------------------------

Old:
----
  SaltTesting-2014.4.24.tar.gz

New:
----
  SaltTesting-2014.8.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-salt-testing.spec ++++++
--- /var/tmp/diff_new_pack.FllUCi/_old  2014-08-06 11:42:35.000000000 +0200
+++ /var/tmp/diff_new_pack.FllUCi/_new  2014-08-06 11:42:35.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           python-salt-testing
-Version:        2014.4.24
+Version:        2014.8.5
 Release:        0
 Summary:        Testing tools needed in the several Salt Stack projects
 License:        Apache-2.0

++++++ SaltTesting-2014.4.24.tar.gz -> SaltTesting-2014.8.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SaltTesting-2014.4.24/PKG-INFO 
new/SaltTesting-2014.8.5/PKG-INFO
--- old/SaltTesting-2014.4.24/PKG-INFO  2014-04-24 14:04:42.000000000 +0200
+++ new/SaltTesting-2014.8.5/PKG-INFO   2014-08-05 17:29:44.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: SaltTesting
-Version: 2014.4.24
+Version: 2014.8.5
 Summary: Required testing tools needed in the several Salt Stack projects.
 Home-page: http://saltstack.org
 Author: Pedro Algarvio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SaltTesting-2014.4.24/SaltTesting.egg-info/PKG-INFO 
new/SaltTesting-2014.8.5/SaltTesting.egg-info/PKG-INFO
--- old/SaltTesting-2014.4.24/SaltTesting.egg-info/PKG-INFO     2014-04-24 
14:04:32.000000000 +0200
+++ new/SaltTesting-2014.8.5/SaltTesting.egg-info/PKG-INFO      2014-08-05 
17:29:39.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: SaltTesting
-Version: 2014.4.24
+Version: 2014.8.5
 Summary: Required testing tools needed in the several Salt Stack projects.
 Home-page: http://saltstack.org
 Author: Pedro Algarvio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/case.py 
new/SaltTesting-2014.8.5/salttesting/case.py
--- old/SaltTesting-2014.4.24/salttesting/case.py       2014-01-20 
16:48:54.000000000 +0100
+++ new/SaltTesting-2014.8.5/salttesting/case.py        2014-06-10 
20:18:34.000000000 +0200
@@ -36,7 +36,8 @@
             arg_str,
             catch_stderr=False,
             with_retcode=False,
-            timeout=None):
+            timeout=None,
+            raw=False):
         '''
         Execute a script with the given argument string
         '''
@@ -133,13 +134,28 @@
             else:
                 out, err = process.communicate()
             # Force closing stderr/stdout to release file descriptors
-            process.stdout.close()
-            process.stderr.close()
+            if process.stdout is not None:
+                process.stdout.close()
+            if process.stderr is not None:
+                process.stderr.close()
             try:
                 if with_retcode:
-                    return out.splitlines(), err.splitlines(), 
process.returncode
+                    if out is not None and err is not None:
+                        if not raw:
+                            return out.splitlines(), err.splitlines(), 
process.returncode
+                        else:
+                            return out, err, process.returncode
+                    return out.splitlines(), [], process.returncode
                 else:
-                    return out.splitlines(), err.splitlines()
+                    if out is not None and err is not None:
+                        if not raw:
+                            return out.splitlines(), err.splitlines()
+                        else:
+                            return out, err
+                    if not raw:
+                        return out.splitlines(), []
+                    else:
+                        return out, []
             finally:
                 try:
                     process.terminate()
@@ -152,9 +168,15 @@
 
         try:
             if with_retcode:
-                return data[0].splitlines(), process.returncode
+                if not raw:
+                    return data[0].splitlines(), process.returncode
+                else:
+                    return data[0], process.returncode
             else:
-                return data[0].splitlines()
+                if not raw:
+                    return data[0].splitlines()
+                else:
+                    return data[0]
         finally:
             try:
                 process.terminate()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/helpers.py 
new/SaltTesting-2014.8.5/salttesting/helpers.py
--- old/SaltTesting-2014.4.24/salttesting/helpers.py    2014-02-08 
02:08:52.000000000 +0100
+++ new/SaltTesting-2014.8.5/salttesting/helpers.py     2014-08-05 
00:38:30.000000000 +0200
@@ -21,17 +21,53 @@
 from functools import wraps
 
 # Import Salt Testing libs
+from salttesting import __version_info__
 from salttesting.unit import skip, _id
 
 log = logging.getLogger(__name__)
 
 
-def destructiveTest(func):
-    @wraps(func)
+def destructiveTest(caller):
+    if inspect.isclass(caller):
+        # We're decorating a class
+        old_setUp = getattr(caller, 'setUp', None)
+
+        def setUp(self, *args, **kwargs):
+            if os.environ.get('DESTRUCTIVE_TESTS', 'False').lower() == 'false':
+                self.skipTest('Destructive tests are disabled')
+            if old_setUp is not None:
+                old_setUp(self, *args, **kwargs)
+        caller.setUp = setUp
+        return caller
+
+    # We're simply decorating functions
+    @wraps(caller)
     def wrap(cls):
         if os.environ.get('DESTRUCTIVE_TESTS', 'False').lower() == 'false':
             cls.skipTest('Destructive tests are disabled')
-        return func(cls)
+        return caller(cls)
+    return wrap
+
+
+def expensiveTest(caller):
+    if inspect.isclass(caller):
+        # We're decorating a class
+        old_setUp = getattr(caller, 'setUp', None)
+
+        def setUp(self, *args, **kwargs):
+            if os.environ.get('EXPENSIVE_TESTS', 'False').lower() == 'false':
+                self.skipTest('Expensive tests are disabled')
+            if old_setUp is not None:
+                old_setUp(self, *args, **kwargs)
+        caller.setUp = setUp
+        return caller
+
+    # We're simply decorating functions
+    @wraps(caller)
+    def wrap(cls):
+        if os.environ.get('EXPENSIVE_TESTS', 'False').lower() == 'false':
+            cls.skipTest('Expensive tests are disabled')
+        return caller(cls)
     return wrap
 
 
@@ -448,19 +484,41 @@
     return decorator
 
 
-def with_system_account(username, on_existing='delete', delete=True):
+def with_system_account(account, on_existing='delete', delete=True):
+    '''
+    This method has been deprecated in favour of ``with_system_user``, please
+    use it instead.
+    '''
+    import warnings
+    caller = inspect.getframeinfo(sys._getframe(1))
+    message = (
+        '\'with_system_account()\' in use in {filename}, line number '
+        '{lineno} has been deprecated in favour of \'with_system_user()\' '
+        'for 8 months now. Please us it instead.'.format(
+            filename=caller.filename,
+            lineno=caller.lineno
+        )
+    )
+    if __version_info__ > (2014, 12):
+        # 8 months should be more than enough to deprecate this
+        raise RuntimeError(message)
+    warnings.warn(message, DeprecationWarning)
+    return with_system_user(account, on_existing=on_existing, delete=delete)
+
+
+def with_system_user(username, on_existing='delete', delete=True):
     '''
-    Create and optionally destroy a system account to be used within a test
-    case. The system account is crated using the ``user`` salt module.
+    Create and optionally destroy a system user to be used within a test
+    case. The system user is crated using the ``user`` salt module.
 
     The decorated testcase function must accept 'username' as an argument.
 
-    :param username: The desired username for the system account.
+    :param username: The desired username for the system user.
     :param on_existing: What to do when the desired username is taken. The
     available options are:
 
-        * nothing: Do nothing, act as if the account was created.
-        * delete: delete and re-create the existing account
+        * nothing: Do nothing, act as if the user was created.
+        * delete: delete and re-create the existing user
         * skip: skip the test case
     '''
     if on_existing not in ('nothing', 'delete', 'skip'):
@@ -479,45 +537,45 @@
         @wraps(func)
         def wrap(cls):
 
-            # Let's add the account to the system.
-            log.debug('Creating system account for {0!r}'.format(username))
-            create_account = cls.run_function('user.add', [username])
-            if not create_account:
-                log.debug('Failed to create system account')
-                # The account was not created
+            # Let's add the user to the system.
+            log.debug('Creating system user {0!r}'.format(username))
+            create_user = cls.run_function('user.add', [username])
+            if not create_user:
+                log.debug('Failed to create system user')
+                # The user was not created
                 if on_existing == 'skip':
                     cls.skipTest(
-                        'Failed to create system account for {0!r}'.format(
+                        'Failed to create system user {0!r}'.format(
                             username
                         )
                     )
 
                 if on_existing == 'delete':
                     log.debug(
-                        'Deleting the system account for {0!r}'.format(
+                        'Deleting the system user {0!r}'.format(
                             username
                         )
                     )
-                    delete_account = cls.run_function(
+                    delete_user = cls.run_function(
                         'user.delete', [username, True, True]
                     )
-                    if not delete_account:
+                    if not delete_user:
                         cls.skipTest(
-                            'An account by the username {0!r} already '
-                            'existed on the system and re-creating it was '
-                            'not possible'.format(username)
+                            'A user named {0!r} already existed on the '
+                            'system and re-creating it was not possible'
+                            .format(username)
                         )
                     log.debug(
-                        'Second time creating system account for {0!r}'.format(
+                        'Second time creating system user {0!r}'.format(
                             username
                         )
                     )
-                    create_account = cls.run_function('user.add', [username])
-                    if not create_account:
+                    create_user = cls.run_function('user.add', [username])
+                    if not create_user:
                         cls.skipTest(
-                            'An account by the username {0!r} already '
-                            'existed, was deleted as requested, but '
-                            're-creating it was not possible'.format(username)
+                            'A user named {0!r} already existed, was deleted '
+                            'as requested, but re-creating it was not possible'
+                            .format(username)
                         )
 
             failure = None
@@ -536,22 +594,282 @@
                     failure = sys.exc_info()
             finally:
                 if delete:
-                    delete_account = cls.run_function(
+                    delete_user = cls.run_function(
                         'user.delete', [username, True, True]
                     )
-                    if not delete_account:
+                    if not delete_user:
+                        if failure is None:
+                            log.warning(
+                                'Although the actual test-case did not fail, '
+                                'deleting the created system user {0!r} '
+                                'afterwards did.'.format(username)
+                            )
+                        else:
+                            log.warning(
+                                'The test-case failed and also did the removal'
+                                ' of the system user {0!r}'.format(username)
+                            )
+                if failure is not None:
+                    # If an exception was thrown, raise it
+                    raise failure[0], failure[1], failure[2]
+        return wrap
+    return decorator
+
+
+def with_system_group(group, on_existing='delete', delete=True):
+    '''
+    Create and optionally destroy a system group to be used within a test
+    case. The system user is crated using the ``group`` salt module.
+
+    The decorated testcase function must accept 'group' as an argument.
+
+    :param group: The desired group name for the system user.
+    :param on_existing: What to do when the desired username is taken. The
+    available options are:
+
+        * nothing: Do nothing, act as if the group was created.
+        * delete: delete and re-create the existing user
+        * skip: skip the test case
+    '''
+    if on_existing not in ('nothing', 'delete', 'skip'):
+        raise RuntimeError(
+            'The value of \'on_existing\' can only be one of, '
+            '\'nothing\', \'delete\' and \'skip\''
+        )
+
+    if not isinstance(delete, bool):
+        raise RuntimeError(
+            'The value of \'delete\' can only be \'True\' or \'False\''
+        )
+
+    def decorator(func):
+
+        @wraps(func)
+        def wrap(cls):
+
+            # Let's add the user to the system.
+            log.debug('Creating system group {0!r}'.format(group))
+            create_group = cls.run_function('group.add', [group])
+            if not create_group:
+                log.debug('Failed to create system group')
+                # The group was not created
+                if on_existing == 'skip':
+                    cls.skipTest(
+                        'Failed to create system group {0!r}'.format(group)
+                    )
+
+                if on_existing == 'delete':
+                    log.debug(
+                        'Deleting the system group {0!r}'.format(group)
+                    )
+                    delete_group = cls.run_function('group.delete', [group])
+                    if not delete_group:
+                        cls.skipTest(
+                            'A group named {0!r} already existed on the '
+                            'system and re-creating it was not possible'
+                            .format(group)
+                        )
+                    log.debug(
+                        'Second time creating system group {0!r}'.format(
+                            group
+                        )
+                    )
+                    create_group = cls.run_function('group.add', [group])
+                    if not create_group:
+                        cls.skipTest(
+                            'A group named {0!r} already existed, was deleted '
+                            'as requested, but re-creating it was not possible'
+                            .format(group)
+                        )
+
+            failure = None
+            try:
+                try:
+                    return func(cls, group)
+                except Exception as exc:  # pylint: disable=W0703
+                    log.error(
+                        'Running {0!r} raised an exception: {1}'.format(
+                            func, exc
+                        ),
+                        exc_info=True
+                    )
+                    # Store the original exception details which will be raised
+                    # a little further down the code
+                    failure = sys.exc_info()
+            finally:
+                if delete:
+                    delete_group = cls.run_function('group.delete', [group])
+                    if not delete_group:
                         if failure is None:
                             log.warning(
-                                'Although the actual test-case did not fail '
-                                'deleting the created system account for '
-                                '{0!r} afterwards did.'.format(username)
+                                'Although the actual test-case did not fail, '
+                                'deleting the created system group {0!r} '
+                                'afterwards did.'.format(group)
                             )
                         else:
                             log.warning(
                                 'The test-case failed and also did the removal'
-                                ' of the system account for {0!r}'.format(
-                                    username
-                                )
+                                ' of the system group {0!r}'.format(group)
+                            )
+                if failure is not None:
+                    # If an exception was thrown, raise it
+                    raise failure[0], failure[1], failure[2]
+        return wrap
+    return decorator
+
+
+def with_system_user_and_group(username, group,
+                               on_existing='delete', delete=True):
+    '''
+    Create and optionally destroy a system user and group to be used within a
+    test case. The system user is crated using the ``user`` salt module, and
+    the system group is created with the ``group`` salt module.
+
+    The decorated testcase function must accept both the 'username' and 'group'
+    arguments.
+
+    :param username: The desired username for the system user.
+    :param group: The desired name for the system group.
+    :param on_existing: What to do when the desired username is taken. The
+    available options are:
+
+        * nothing: Do nothing, act as if the user was created.
+        * delete: delete and re-create the existing user
+        * skip: skip the test case
+    '''
+    if on_existing not in ('nothing', 'delete', 'skip'):
+        raise RuntimeError(
+            'The value of \'on_existing\' can only be one of, '
+            '\'nothing\', \'delete\' and \'skip\''
+        )
+
+    if not isinstance(delete, bool):
+        raise RuntimeError(
+            'The value of \'delete\' can only be \'True\' or \'False\''
+        )
+
+    def decorator(func):
+
+        @wraps(func)
+        def wrap(cls):
+
+            # Let's add the user to the system.
+            log.debug('Creating system user {0!r}'.format(username))
+            create_user = cls.run_function('user.add', [username])
+            log.debug('Creating system group {0!r}'.format(group))
+            create_group = cls.run_function('group.add', [group])
+            if not create_user:
+                log.debug('Failed to create system user')
+                # The user was not created
+                if on_existing == 'skip':
+                    cls.skipTest(
+                        'Failed to create system user {0!r}'.format(
+                            username
+                        )
+                    )
+
+                if on_existing == 'delete':
+                    log.debug(
+                        'Deleting the system user {0!r}'.format(
+                            username
+                        )
+                    )
+                    delete_user = cls.run_function(
+                        'user.delete', [username, True, True]
+                    )
+                    if not delete_user:
+                        cls.skipTest(
+                            'A user named {0!r} already existed on the '
+                            'system and re-creating it was not possible'
+                            .format(username)
+                        )
+                    log.debug(
+                        'Second time creating system user {0!r}'.format(
+                            username
+                        )
+                    )
+                    create_user = cls.run_function('user.add', [username])
+                    if not create_user:
+                        cls.skipTest(
+                            'A user named {0!r} already existed, was deleted '
+                            'as requested, but re-creating it was not possible'
+                            .format(username)
+                        )
+            if not create_group:
+                log.debug('Failed to create system group')
+                # The group was not created
+                if on_existing == 'skip':
+                    cls.skipTest(
+                        'Failed to create system group {0!r}'.format(group)
+                    )
+
+                if on_existing == 'delete':
+                    log.debug(
+                        'Deleting the system group {0!r}'.format(group)
+                    )
+                    delete_group = cls.run_function('group.delete', [group])
+                    if not delete_group:
+                        cls.skipTest(
+                            'A group named {0!r} already existed on the '
+                            'system and re-creating it was not possible'
+                            .format(group)
+                        )
+                    log.debug(
+                        'Second time creating system group {0!r}'.format(
+                            group
+                        )
+                    )
+                    create_group = cls.run_function('group.add', [group])
+                    if not create_group:
+                        cls.skipTest(
+                            'A group named {0!r} already existed, was deleted '
+                            'as requested, but re-creating it was not possible'
+                            .format(group)
+                        )
+
+            failure = None
+            try:
+                try:
+                    return func(cls, username, group)
+                except Exception as exc:  # pylint: disable=W0703
+                    log.error(
+                        'Running {0!r} raised an exception: {1}'.format(
+                            func, exc
+                        ),
+                        exc_info=True
+                    )
+                    # Store the original exception details which will be raised
+                    # a little further down the code
+                    failure = sys.exc_info()
+            finally:
+                if delete:
+                    delete_user = cls.run_function(
+                        'user.delete', [username, True, True]
+                    )
+                    delete_group = cls.run_function('group.delete', [group])
+                    if not delete_user:
+                        if failure is None:
+                            log.warning(
+                                'Although the actual test-case did not fail, '
+                                'deleting the created system user {0!r} '
+                                'afterwards did.'.format(username)
+                            )
+                        else:
+                            log.warning(
+                                'The test-case failed and also did the removal'
+                                ' of the system user {0!r}'.format(username)
+                            )
+                    if not delete_group:
+                        if failure is None:
+                            log.warning(
+                                'Although the actual test-case did not fail, '
+                                'deleting the created system group {0!r} '
+                                'afterwards did.'.format(group)
+                            )
+                        else:
+                            log.warning(
+                                'The test-case failed and also did the removal'
+                                ' of the system group {0!r}'.format(group)
                             )
                 if failure is not None:
                     # If an exception was thrown, raise it
@@ -587,12 +905,12 @@
     def decorator(caller):
 
         if inspect.isclass(caller):
-
             # We're decorating a class
-            old_init = caller.__init__
+            old_setUp = getattr(caller, 'setUp', None)
 
-            def new_init(self, *args, **kwargs):
-                old_init(self, *args, **kwargs)
+            def setUp(self, *args, **kwargs):
+                if old_setUp is not None:
+                    old_setUp(self, *args, **kwargs)
 
                 if not hasattr(self, 'run_function'):
                     raise RuntimeError(
@@ -603,16 +921,12 @@
                     )
 
                 for name in names:
-                    if name not in self.run_function('sys.doc'):
-                        reason = 'Salt module {0!r} is not available'.format(
-                            name
-                        )
-                        for fname in dir(self):
-                            if not fname.startswith('test_'):
-                                continue
-                            setattr(self, fname, lambda: self.skipTest(reason))
-                        break
-            caller.__init__ = new_init
+                    if not hasattr(self, '__salt_sys_docs__'):
+                        # cache salts documentation
+                        self.__salt_sys_docs__ = self.run_function('sys.doc')
+                    if name not in self.__salt_sys_docs__:
+                        self.skipTest('Salt module {0!r} is not 
available'.format(name))
+            caller.setUp = setUp
             return caller
 
         # We're simply decorating functions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/mock.py 
new/SaltTesting-2014.8.5/salttesting/mock.py
--- old/SaltTesting-2014.4.24/salttesting/mock.py       2014-01-02 
12:03:08.000000000 +0100
+++ new/SaltTesting-2014.8.5/salttesting/mock.py        2014-08-05 
01:16:27.000000000 +0200
@@ -38,6 +38,8 @@
 
     # Let's not fail on imports by providing fake objects and classes
 
+    Mock = MagicMock
+
     class MagicMock(object):
 
         __name__ = '{0}.fakemock'.format(__name__)
@@ -54,7 +56,6 @@
         def __call__(self, *args, **kwargs):
             return self
 
-    Mock = MagicMock
     patch = MagicMock()
     sentinel = object()
     DEFAULT = object()
@@ -62,6 +63,8 @@
     FILTER_DIR = True
     NonCallableMock = MagicMock()
     NonCallableMagicMock = MagicMock()
+    mock_open = object()
+    PropertyMock = object()
     call = tuple
     ANY = object()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/parser/__init__.py 
new/SaltTesting-2014.8.5/salttesting/parser/__init__.py
--- old/SaltTesting-2014.4.24/salttesting/parser/__init__.py    2014-04-18 
02:21:34.000000000 +0200
+++ new/SaltTesting-2014.8.5/salttesting/parser/__init__.py     2014-08-05 
00:38:30.000000000 +0200
@@ -92,6 +92,7 @@
 class SaltTestingParser(optparse.OptionParser):
     support_docker_execution = False
     support_destructive_tests_selection = False
+    support_expensive_tests_selection = False
     source_code_basedir = None
 
     _known_interpreters = {
@@ -153,6 +154,15 @@
                       'or removing users from your system for example. '
                       'Default: %default')
             )
+        if self.support_expensive_tests_selection is True:
+            self.test_selection_group.add_option(
+                '--run-expensive',
+                action='store_true',
+                default=False,
+                help=('Run expensive tests. Expensive tests are any tests 
that, '
+                      'once configured, cost money to run, such as creating or 
'
+                      'destroying cloud instances on a cloud provider.')
+            )
 
         self.test_selection_group.add_option(
             '-n',
@@ -199,6 +209,11 @@
                 help='Skip docker container deletion on exit if errors '
                      'occurred. Default: False'
             )
+            self.docked_selection_group.add_option(
+                '--docker-binary',
+                help='The docker binary on the host system. Default: %default',
+                default='/usr/bin/docker',
+            )
             self.add_option_group(self.docked_selection_group)
 
         self.output_options_group = optparse.OptionGroup(
@@ -339,6 +354,11 @@
             # destructive tests should be executed or not.
             os.environ['DESTRUCTIVE_TESTS'] = str(self.options.run_destructive)
 
+        if self.support_expensive_tests_selection:
+            # Set the required environment variable in order to know if
+            # expensive tests should be executed or not.
+            os.environ['EXPENSIVE_TESTS'] = str(self.options.run_expensive)
+
     def validate_options(self):
         '''
         Validate the provided options. Override this method to run your own
@@ -702,7 +722,7 @@
             tempfile.mktemp(prefix='docked-testsuite-', suffix='.cid')
         )
         call = subprocess.Popen(
-            ['docker',
+            [self.options.docker_binary,
              'run',
              #'--rm=true', Do not remove the container automatically, we need
              #             to get information back, even for stopped containers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/SaltTesting-2014.4.24/salttesting/pylintplugins/pep8.py 
new/SaltTesting-2014.8.5/salttesting/pylintplugins/pep8.py
--- old/SaltTesting-2014.4.24/salttesting/pylintplugins/pep8.py 2014-04-15 
10:37:43.000000000 +0200
+++ new/SaltTesting-2014.8.5/salttesting/pylintplugins/pep8.py  2014-06-10 
20:19:41.000000000 +0200
@@ -13,6 +13,8 @@
 
 # Let's use absolute imports
 from __future__ import absolute_import
+import sys
+import logging
 
 # Import PyLint libs
 from pylint.interfaces import IRawChecker
@@ -25,13 +27,16 @@
     HAS_PEP8 = True
 except ImportError:
     HAS_PEP8 = False
-    import logging
-    logging.getLogger(__name__).warning(
-        'No pep8 library could be imported. No PEP8 check\'s will be done'
-    )
+    msg = 'No pep8 library could be imported. No PEP8 check\'s will be done'
+    if logging.root.handlers:
+        logging.getLogger(__name__).warning(msg)
+    else:
+        sys.stderr.write('{0}\n'.format(msg))
 
 
 _PROCESSED_NODES = {}
+_KNOWN_PEP8_IDS = []
+_UNHANDLED_PEP8_IDS = []
 
 
 if HAS_PEP8 is True:
@@ -95,12 +100,25 @@
                 # This will be handled by PyLint itself, skip it
                 continue
 
-            if pylintcode not in self.msgs:
-                # Log warning??
+            if pylintcode not in _KNOWN_PEP8_IDS:
+                if pylintcode not in _UNHANDLED_PEP8_IDS:
+                    _UNHANDLED_PEP8_IDS.append(pylintcode)
+                    msg = 'The following code, {0}, was not handled by the 
PEP8 plugin'.format(pylintcode)
+                    if logging.root.handlers:
+                        logging.getLogger(__name__).warning(msg)
+                    else:
+                        sys.stderr.write('{0}\n'.format(msg))
                 continue
 
-            if code == 'E113':
+            if pylintcode not in self._msgs:
+                # Not for our class implementation to handle
+                continue
+
+            if code in ('E111', 'E113'):
                 if 
_PROCESSED_NODES[node.path].lines[lineno-1].strip().startswith('#'):
+                    # If E111 is triggered in a comment I consider it, at
+                    # least, bad judgement. See 
https://github.com/jcrocholl/pep8/issues/300
+
                     # If E113 is triggered in comments, which I consider a bug,
                     # skip it. See https://github.com/jcrocholl/pep8/issues/274
                     continue
@@ -137,10 +155,18 @@
                   'continuation-line-over-indented-for-visual-indent'),
         'E8128': ('PEP8 %s: continuation line under-indented for visual 
indent',
                   'continuation-line-under-indented-for-visual-indent'),
+        'E8129': ('PEP8 %s: visually indented line with same indent as next 
logical line',
+                  
'visually-indented-line-with-same-indent-as-next-logical-line'),
+        'E8131': ('PEP8 %s: unaligned for hanging indent',
+                  'unaligned-for-hanging-indent'),
         'E8133': ('PEP8 %s: closing bracket is missing indentation',
                   'closing-bracket-is-missing-indentation'),
     }
 
+    msgs_map = {
+        'E8126': 'C0330'
+    }
+
 
 class PEP8Whitespace(_PEP8BaseChecker):
     '''
@@ -176,6 +202,8 @@
                   'at-least-two-spaces-before-inline-comment'),
         'E8262': ("PEP8 %s: inline comment should start with '# '",
                   "inline-comment-should-start-with-'#-'"),
+        'E8265': ("PEP8 %s: block comment should start with '# '",
+                  "block-comment-should-start-with-'# '"),
         'E8271': ('PEP8 %s: multiple spaces after keyword',
                   'multiple-spaces-after-keyword'),
         'E8272': ('PEP8 %s: multiple spaces before keyword',
@@ -184,6 +212,11 @@
         'E8274': ('PEP8 %s: tab before keyword', 'tab-before-keyword'),
     }
 
+    msgs_map = {
+        'E8222': 'C0326',
+        'E8251': 'C0326'
+    }
+
 
 class PEP8BlankLine(_PEP8BaseChecker):
     '''
@@ -246,6 +279,10 @@
                   "comparison-to-None-should-be-'if-cond-is-None:'"),
         'E8712': ("PEP8 %s: comparison to True should be 'if cond is True:' or 
'if cond:'",
                   
"comparison-to-True-should-be-'if-cond-is-True:'-or-'if-cond:'"),
+        'E8713': ("PEP8 %s: test for membership should be 'not in'",
+                  "test-for-membership-should-be 'not in'"),
+        'E8714': ("PEP8 %s: test for object identity should be 'is not'",
+                  "test-for-object-identity-should-be-'is not'"),
         'E8721': ("PEP8 %s: do not compare types, use 'isinstance()'",
                   "do-not-compare-types,-use-'isinstance()'"),
     }
@@ -288,6 +325,11 @@
                   'blank-line-contains-whitespace'),
     }
 
+    msgs_map = {
+        'W8291': 'C0303',
+        'W8293': 'C0303'
+    }
+
 
 class PEP8BlankLineWarning(_PEP8BaseChecker):
     '''
@@ -317,6 +359,17 @@
     }
 
 
+# ----- Keep Track Of Handled PEP8 MSG IDs 
-------------------------------------------------------------------------->
+for checker in locals().values():
+    try:
+        if issubclass(checker, _PEP8BaseChecker):
+            _KNOWN_PEP8_IDS.extend(checker._msgs.keys())
+    except TypeError:
+        # Not class
+        continue
+# <---- Keep Track Of Handled PEP8 MSG IDs 
---------------------------------------------------------------------------
+
+
 def register(linter):
     '''
     required method to auto register this checker
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/SaltTesting-2014.4.24/salttesting/pylintplugins/strings.py 
new/SaltTesting-2014.8.5/salttesting/pylintplugins/strings.py
--- old/SaltTesting-2014.4.24/salttesting/pylintplugins/strings.py      
2014-01-12 22:17:08.000000000 +0100
+++ new/SaltTesting-2014.8.5/salttesting/pylintplugins/strings.py       
2014-06-10 20:18:34.000000000 +0200
@@ -11,6 +11,7 @@
     Extended String Formatting Checkers
 '''
 
+import re
 import sys
 try:
     # >= pylint 1.0
@@ -19,7 +20,7 @@
     from logilab import astng as astroid
 from pylint.checkers import utils
 from pylint.checkers import BaseChecker
-from pylint.checkers.utils import check_messages
+from pylint.checkers.utils import check_messages, parse_format_string
 
 try:
     # >= pylint 1.0
@@ -36,9 +37,17 @@
     'E1320': ('String format call with un-indexed curly braces: %r',
               'un-indexed-curly-braces-error',
               'Under python 2.6 the curly braces on a \'string.format()\' '
-              'call MUST be indexed.')
+              'call MUST be indexed.'),
+    'W1321': ('String substitution used instead of string formattting on: %r',
+              'string-substitution-usage-warning',
+              'String substitution used instead of string formattting'),
+    'E1321': ('String substitution used instead of string formattting on: %r',
+              'string-substitution-usage-error',
+              'String substitution used instead of string formattting'),
 }
 
+BAD_FORMATTING_SLOT = re.compile(r'(\{![\w]{1}\}|\{\})')
+
 
 class StringCurlyBracesFormatIndexChecker(BaseChecker):
 
@@ -53,15 +62,52 @@
                  'help': 'Force un-indexed curly braces on a '
                          '\'string.format()\' call to always be an error.'}
                 ),
+                ('enforce-string-formatting-over-substitution',
+                 {'default': 1, 'type': 'yn', 'metavar': '<y_or_n>',
+                  'help': 'Enforce string formatting over string substitution'}
+                 ),
+                ('string-substitutions-usage-is-an-error',
+                 {'default': 1, 'type': 'yn', 'metavar': '<y_or_n>',
+                  'help': 'Force string substitution usage on strings '
+                          'to always be an error.'}
+                 ),
                )
 
     @check_messages(*(MSGS.keys()))
+    def visit_binop(self, node):
+        if not self.config.enforce_string_formatting_over_substitution:
+            return
+
+        if node.op != '%':
+            return
+
+        if not (isinstance(node.left, astroid.Const) and
+                isinstance(node.left.value, basestring)):
+            return
+
+        try:
+            required_keys, required_num_args = 
parse_format_string(node.left.value)
+        except (utils.UnsupportedFormatCharacter, 
utils.IncompleteFormatString):
+            # This is handled elsewere
+            return
+
+        if required_keys or required_num_args:
+            if self.config.string_substitutions_usage_is_an_error:
+                msgid = 'E1321'
+            else:
+                msgid = 'W1321'
+            self.add_message(
+                msgid, node=node.left, args=node.left.value
+            )
+
+
+    @check_messages(*(MSGS.keys()))
     def visit_callfunc(self, node):
         func = utils.safe_infer(node.func)
         if isinstance(func, astroid.BoundMethod) and func.name == 'format':
             # If there's a .format() call, run the code below
 
-            if isinstance(node.func.expr, astroid.Name):
+            if isinstance(node.func.expr, (astroid.Name, astroid.Const)):
                 # This is for:
                 #   foo = 'Foo {} bar'
                 #   print(foo.format(blah)
@@ -71,7 +117,7 @@
                         # checking.
                         continue
 
-                    if '{}' in inferred.value:
+                    if BAD_FORMATTING_SLOT.findall(inferred.value):
                         if self.config.un_indexed_curly_braces_always_error or 
\
                                 sys.version_info[:2] < (2, 7):
                             msgid = 'E1320'
@@ -87,7 +133,7 @@
             elif isinstance(node.func.expr.value, astroid.Name):
                 # No need to check these either
                 return
-            elif '{}' in node.func.expr.value:
+            elif BAD_FORMATTING_SLOT.findall(node.func.expr.value):
                 if self.config.un_indexed_curly_braces_always_error or \
                         sys.version_info[:2] < (2, 7):
                     msgid = 'E1320'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/version.py 
new/SaltTesting-2014.8.5/salttesting/version.py
--- old/SaltTesting-2014.4.24/salttesting/version.py    2014-04-24 
14:02:39.000000000 +0200
+++ new/SaltTesting-2014.8.5/salttesting/version.py     2014-08-05 
01:20:18.000000000 +0200
@@ -8,5 +8,5 @@
     :license: Apache 2.0, see LICENSE for more details.
 '''
 
-__version_info__ = (2014, 4, 24)
+__version_info__ = (2014, 8, 5)
 __version__ = '.'.join(map(str, __version_info__))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/xmlunit.py 
new/SaltTesting-2014.8.5/salttesting/xmlunit.py
--- old/SaltTesting-2014.4.24/salttesting/xmlunit.py    2014-02-09 
03:01:05.000000000 +0100
+++ new/SaltTesting-2014.8.5/salttesting/xmlunit.py     2014-06-23 
01:45:37.000000000 +0200
@@ -12,12 +12,20 @@
 '''
 
 # Import python libs
+import sys
 import logging
 
 try:
     import xmlrunner
     HAS_XMLRUNNER = True
 
+    class _DelegateIO(xmlrunner._DelegateIO):
+        def __getattr__(self, attr):
+            try:
+                return getattr(self._captured, attr)
+            except AttributeError:
+                return getattr(self.delegate, attr)
+
     class _XMLTestResult(xmlrunner._XMLTestResult):
         def startTest(self, test):
             logging.getLogger(__name__).debug(
@@ -47,6 +55,14 @@
             self.stream.writeln('Finished generating XML reports')
             return result
 
+        def _patch_standard_output(self):
+            '''
+            Replaces stdout and stderr streams with string-based streams
+            in order to capture the tests' output.
+            '''
+            sys.stdout = _DelegateIO(sys.stdout)
+            sys.stderr = _DelegateIO(sys.stderr)
+
 except ImportError:
     HAS_XMLRUNNER = False
 

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to