diff --git a/salt/loader.py b/salt/loader.py index afa9b1b749..b33efc1c6c 100644 --- a/salt/loader.py +++ b/salt/loader.py @@ -21,6 +21,7 @@ from salt.template import check_render_pipe_str from salt.utils.decorators import Depends import salt.utils.lazy import salt.utils.event +import salt.utils.odict # Solve the Chicken and egg problem where grains need to run before any # of the modules are loaded and are generally available for any usage. diff --git a/salt/utils/compat.py b/salt/utils/compat.py new file mode 100644 index 0000000000..1fa0b4c810 --- /dev/null +++ b/salt/utils/compat.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +''' +Compatibility functions for utils +''' + +# Import python libs +from __future__ import absolute_import +import sys + +# Import salt libs +import salt.loader + + +def pack_dunder(name): + ''' + Compatibility helper function to make __utils__ available on demand. + ''' + # TODO: Deprecate starting with Beryllium + + mod = sys.modules[name] + if not hasattr(mod, '__utils__'): + setattr(mod, '__utils__', salt.loader.utils(mod.__opts__)) diff --git a/tests/unit/modules/pkg_resource_test.py b/tests/unit/modules/pkg_resource_test.py new file mode 100644 index 0000000000..5aca55263e --- /dev/null +++ b/tests/unit/modules/pkg_resource_test.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +''' + :codeauthor: :email:`Rahul Handay ` +''' + +# Import Salt Testing Libs +from salttesting import TestCase, skipIf +from salttesting.mock import ( + MagicMock, + patch, + NO_MOCK, + NO_MOCK_REASON +) + +# Import Salt Libs +import salt.utils +from salt.modules import pkg_resource +import yaml + +# Globals +pkg_resource.__grains__ = {} +pkg_resource.__salt__ = {} + + +@skipIf(NO_MOCK, NO_MOCK_REASON) +class PkgresTestCase(TestCase): + ''' + Test cases for salt.modules.pkg_resource + ''' + def test_pack_sources(self): + ''' + Test to accepts list of dicts (or a string representing a + list of dicts) and packs the key/value pairs into a single dict. + ''' + with patch.object(yaml, + 'safe_load', + MagicMock(side_effect=yaml.parser.ParserError('f'))): + with patch.dict(pkg_resource.__salt__, + {'pkg.normalize_name': MagicMock()}): + self.assertDictEqual(pkg_resource.pack_sources('sources'), {}) + + self.assertDictEqual(pkg_resource.pack_sources(['A', 'a']), {}) + + self.assertTrue(pkg_resource.pack_sources([{'A': 'a'}])) + + def test_parse_targets(self): + ''' + Test to parses the input to pkg.install and + returns back the package(s) to be installed. Returns a + list of packages, as well as a string noting whether the + packages are to come from a repository or a binary package. + ''' + with patch.dict(pkg_resource.__grains__, {'os': 'A'}): + self.assertEqual(pkg_resource.parse_targets(pkgs='a', + sources='a'), + (None, None)) + + with patch.object(pkg_resource, '_repack_pkgs', + return_value=False): + self.assertEqual(pkg_resource.parse_targets(pkgs='a'), + (None, None)) + + with patch.object(pkg_resource, '_repack_pkgs', + return_value='A'): + self.assertEqual(pkg_resource.parse_targets(pkgs='a'), + ('A', 'repository')) + + with patch.dict(pkg_resource.__grains__, {'os': 'MacOS1'}): + with patch.object(pkg_resource, 'pack_sources', + return_value=False): + self.assertEqual(pkg_resource.parse_targets(sources='s'), + (None, None)) + + with patch.object(pkg_resource, 'pack_sources', + return_value={'A': 'a'}): + with patch.dict(pkg_resource.__salt__, + {'config.valid_fileproto': + MagicMock(return_value=False)}): + self.assertEqual(pkg_resource.parse_targets(sources='s'), + (['a'], 'file')) + + with patch.object(pkg_resource, 'pack_sources', + return_value={'A': 'a'}): + with patch.dict(pkg_resource.__salt__, + {'config.valid_fileproto': + MagicMock(return_value=False)}): + self.assertEqual(pkg_resource.parse_targets(name='n'), + ({'n': None}, 'repository')) + + self.assertEqual(pkg_resource.parse_targets(), + (None, None)) + + def test_version(self): + ''' + Test to Common interface for obtaining the version + of installed packages. + ''' + with patch.object(salt.utils, 'is_true', return_value=True): + mock = MagicMock(return_value={'A': 'B'}) + with patch.dict(pkg_resource.__salt__, + {'pkg.list_pkgs': mock}): + self.assertEqual(pkg_resource.version('A'), 'B') + + self.assertDictEqual(pkg_resource.version(), {}) + + mock = MagicMock(return_value={}) + with patch.dict(pkg_resource.__salt__, {'pkg.list_pkgs': mock}): + with patch('__builtin__.next') as mock_next: + mock_next.side_effect = StopIteration() + self.assertEqual(pkg_resource.version('A'), '') + + def test_add_pkg(self): + ''' + Test to add a package to a dict of installed packages. + ''' + self.assertIsNone(pkg_resource.add_pkg('pkgs', 'name', 'version')) + + def test_sort_pkglist(self): + ''' + Test to accepts a dict obtained from pkg.list_pkgs() and sorts + in place the list of versions for any packages that have multiple + versions installed, so that two package lists can be compared + to one another. + ''' + self.assertIsNone(pkg_resource.sort_pkglist({})) + + def test_stringify(self): + ''' + Test to takes a dict of package name/version information + and joins each list of + installed versions into a string. + ''' + self.assertIsNone(pkg_resource.stringify({})) + + def test_version_clean(self): + ''' + Test to clean the version string removing extra data. + ''' + with patch.dict(pkg_resource.__salt__, {'pkg.version_clean': + MagicMock(return_value='A')}): + self.assertEqual(pkg_resource.version_clean('version'), 'A') + + self.assertEqual(pkg_resource.version_clean('v'), 'v') + + def test_check_extra_requirements(self): + ''' + Test to check if the installed package already + has the given requirements. + ''' + with patch.dict(pkg_resource.__salt__, {'pkg.check_extra_requirements': + MagicMock(return_value='A')}): + self.assertEqual(pkg_resource.check_extra_requirements('a', 'b'), + 'A') + + self.assertTrue(pkg_resource.check_extra_requirements('a', False)) + + +if __name__ == '__main__': + from integration import run_tests + run_tests(PkgresTestCase, needs_daemon=False)