Hello community, here is the log from the commit of package salt for openSUSE:Leap:15.2 checked in at 2020-04-08 12:48:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/salt (Old) and /work/SRC/openSUSE:Leap:15.2/.salt.new.3248 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "salt" Wed Apr 8 12:48:17 2020 rev:69 rq:791027 version:2019.2.3 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/salt/salt.changes 2020-03-23 09:33:43.408304977 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.salt.new.3248/salt.changes 2020-04-08 12:48:52.994357864 +0200 @@ -1,0 +2,31 @@ +Thu Apr 2 13:47:34 UTC 2020 - Pablo Suárez Hernández <pablo.suarezhernan...@suse.com> + +- Enable building and installation for Fedora +- Disable python2 build on Tumbleweed + We are removing the python2 interpreter from openSUSE (SLE16). + As such disable salt building for python2 there. + +------------------------------------------------------------------- +Thu Apr 2 10:54:53 UTC 2020 - Pablo Suárez Hernández <pablo.suarezhernan...@suse.com> + +- Sanitize grains loaded from roster_grains.json cache during "state.pkg" + +- Added: + * fix-load-cached-grain-osrelease_info.patch + +------------------------------------------------------------------- +Fri Mar 27 15:37:10 UTC 2020 - Jochen Breuer <jbre...@suse.de> + +- Build: Buildequire pkgconfig(systemd) instead of systemd + +------------------------------------------------------------------- +Thu Mar 26 13:18:50 UTC 2020 - Pablo Suárez Hernández <pablo.suarezhernan...@suse.com> + +- Backport saltutil state module to 2019.2 codebase (bsc#1167556) +- Add new custom SUSE capability for saltutil state module + +- Added: + * backport-saltutil-state-module-to-2019.2-codebase.patch + * add-new-custom-suse-capability-for-saltutil-state-mo.patch + +------------------------------------------------------------------- New: ---- add-new-custom-suse-capability-for-saltutil-state-mo.patch backport-saltutil-state-module-to-2019.2-codebase.patch fix-load-cached-grain-osrelease_info.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ salt.spec ++++++ --- /var/tmp/diff_new_pack.EPCQX3/_old 2020-04-08 12:48:57.818360378 +0200 +++ /var/tmp/diff_new_pack.EPCQX3/_new 2020-04-08 12:48:57.822360381 +0200 @@ -15,8 +15,12 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # %global debug_package %{nil} - -%if 0%{?suse_version} >= 1320 +%if 0%{?suse_version} > 1500 +%global build_py3 1 +%global build_py2 0 +%global default_py3 1 +%else +%if 0%{?suse_version} >= 1500 # SLE15 %global build_py3 1 %global build_py2 1 @@ -36,9 +40,10 @@ %endif %endif %endif +%endif %define pythonX %{?default_py3: python3}%{!?default_py3: python2} -%if 0%{?suse_version} > 1210 || 0%{?rhel} >= 7 || 0%{?fedora} +%if 0%{?suse_version} > 1210 || 0%{?rhel} >= 7 || 0%{?fedora} >=28 %bcond_without systemd %else %bcond_with systemd @@ -310,6 +315,13 @@ Patch114: open-suse-2019.2.3-virt-defined-states-219.patch # PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/56392 Patch115: virt._get_domain-don-t-raise-an-exception-if-there-i.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/50197 +Patch116: backport-saltutil-state-module-to-2019.2-codebase.patch +# PATCH_FIX_OPENSUSE: https://github.com/openSUSE/salt/commit/b713d0b3031faadc17cd9cf09977ccc19e50bef7 +Patch117: add-new-custom-suse-capability-for-saltutil-state-mo.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/55796 +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/56491 +Patch118: fix-load-cached-grain-osrelease_info.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -348,8 +360,8 @@ %endif %if %{with systemd} -BuildRequires: systemd -%{?systemd_requires} +BuildRequires: pkgconfig(systemd) +%{?systemd_ordering} %else %if 0%{?suse_version} Requires(pre): %insserv_prereq @@ -373,7 +385,7 @@ BuildRequires: zsh %endif -%if 0%{?rhel} +%if 0%{?rhel} || 0%{?fedora} BuildRequires: yum %endif @@ -393,7 +405,7 @@ BuildRequires: python >= 2.7 BuildRequires: python-devel >= 2.7 # requirements/base.txt -%if 0%{?rhel} +%if 0%{?rhel} || 0%{?fedora} BuildRequires: python-jinja2 BuildRequires: python-yaml BuildRequires: python-markupsafe @@ -407,7 +419,7 @@ BuildRequires: python-msgpack-python > 0.3 BuildRequires: python-psutil BuildRequires: python-requests >= 1.0.0 -%if 0%{?suse_version} >= 1500 || 0%{?rhel} >= 8 +%if 0%{?suse_version} >= 1500 || 0%{?rhel} >= 8 || 0%{?fedora} >= 30 # We can't cope with tornado 5.x and newer (boo#1101780); this is only relevant for SLE >= 15 and TW # where tornado exists in multiple versions BuildRequires: (python-tornado >= 4.2.1 with python-tornado < 5) @@ -443,7 +455,7 @@ Requires: python-certifi %endif # requirements/base.txt -%if 0%{?rhel} +%if 0%{?rhel} || 0%{?fedora} Requires: python-jinja2 Requires: python-yaml Requires: python-markupsafe @@ -507,7 +519,7 @@ %endif BuildRequires: python3-devel # requirements/base.txt -%if 0%{?rhel} +%if 0%{?rhel} || 0%{?fedora} BuildRequires: python3-jinja2 BuildRequires: python3-markupsafe BuildRequires: python3-msgpack > 0.3 @@ -528,7 +540,7 @@ BuildRequires: python3-PyYAML BuildRequires: python3-psutil BuildRequires: python3-requests >= 1.0.0 -%if 0%{?suse_version} >= 1500 || 0%{?rhel} >= 8 +%if 0%{?suse_version} >= 1500 || 0%{?rhel} >= 8 || 0%{?fedora} >= 30 # We can't cope with tornado 5.x and newer (boo#1101780); this is only relevant for SLE >= 15 and TW, # where tornado exists in multiple versions BuildRequires: (python3-tornado >= 4.2.1 with python3-tornado < 5) @@ -562,14 +574,15 @@ Requires: python3-certifi %endif # requirements/base.txt -%if 0%{?rhel} +%if 0%{?rhel} || 0%{?fedora} Requires: python3-jinja2 Requires: yum Requires: python3-markupsafe Requires: python3-msgpack > 0.3 Requires: python3-m2crypto Requires: python3-zmq >= 2.2.0 -%if 0%{?rhel} == 8 + +%if 0%{?rhel} == 8 || 0%{?fedora} >= 30 Requires: dnf %endif %if 0%{?rhel} == 6 @@ -952,6 +965,9 @@ %patch113 -p1 %patch114 -p1 %patch115 -p1 +%patch116 -p1 +%patch117 -p1 +%patch118 -p1 %build %if 0%{?build_py2} ++++++ _lastrevision ++++++ --- /var/tmp/diff_new_pack.EPCQX3/_old 2020-04-08 12:48:57.898360420 +0200 +++ /var/tmp/diff_new_pack.EPCQX3/_new 2020-04-08 12:48:57.898360420 +0200 @@ -1 +1 @@ -6c4669ed512eb32e435e4bfd2cebdcba315841bb \ No newline at end of file +eb41abdc4d70c344f2d84dc6d693b9fb9cb4c247 \ No newline at end of file ++++++ add-new-custom-suse-capability-for-saltutil-state-mo.patch ++++++ >From 4a8c36db7ece51efdd04caa37c79b0cb6a22ecf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= <psuarezhernan...@suse.com> Date: Thu, 26 Mar 2020 13:08:16 +0000 Subject: [PATCH] Add new custom SUSE capability for saltutil state module --- salt/grains/extra.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/salt/grains/extra.py b/salt/grains/extra.py index 4fb58674bf04d44ada1cb1620384aba7d3a76bad..e78cc64e0dedc728cbef68942b8767c526daa1a8 100644 --- a/salt/grains/extra.py +++ b/salt/grains/extra.py @@ -80,5 +80,6 @@ def config(): def suse_backported_capabilities(): return { '__suse_reserved_pkg_all_versions_support': True, - '__suse_reserved_pkg_patches_support': True + '__suse_reserved_pkg_patches_support': True, + '__suse_reserved_saltutil_states_support': True } -- 2.23.0 ++++++ backport-saltutil-state-module-to-2019.2-codebase.patch ++++++ >From d99badeda9818ba54a3af1d0145c5278fe0edee1 Mon Sep 17 00:00:00 2001 From: Christian McHugh <mchu...@dnb.com> Date: Wed, 24 Oct 2018 15:49:58 +0100 Subject: [PATCH] Backport "saltutil" state module to 2019.2 codebase add individual syncers and release note add individual syncers adjust state comment output and cleanup tests --- salt/states/saltutil.py | 311 +++++++++++++++++++++++++++++ tests/unit/states/test_saltutil.py | 121 +++++++++++ 2 files changed, 432 insertions(+) create mode 100644 salt/states/saltutil.py create mode 100644 tests/unit/states/test_saltutil.py diff --git a/salt/states/saltutil.py b/salt/states/saltutil.py new file mode 100644 index 0000000000000000000000000000000000000000..99952a1b7d1b8a70bac940ec083eb75776c146c6 --- /dev/null +++ b/salt/states/saltutil.py @@ -0,0 +1,311 @@ +# -*- coding: utf-8 -*- +''' +Saltutil State +============== + +This state wraps the saltutil execution modules to make them easier to run +from a states. Rather than needing to to use ``module.run`` this state allows for +improved change detection. + + .. versionadded: Neon +''' +from __future__ import absolute_import, unicode_literals, print_function + +import logging + +# Define the module's virtual name +__virtualname__ = 'saltutil' + +log = logging.getLogger(__name__) + + +def __virtual__(): + ''' + Named saltutil + ''' + return __virtualname__ + + +def _sync_single(name, module, **kwargs): + ret = {'name': name, 'changes': {}, 'result': True, 'comment': ''} + + if __opts__['test']: + ret['result'] = None + ret['comment'] = "saltutil.sync_{0} would have been run".format(module) + return ret + + try: + sync_status = __salt__['saltutil.sync_{0}'.format(module)](**kwargs) + if sync_status: + ret['changes'][module] = sync_status + ret['comment'] = "Updated {0}.".format(module) + except Exception as e: + log.error("Failed to run saltutil.sync_%s: %s", module, e) + ret['result'] = False + ret['comment'] = "Failed to run sync_{0}: {1}".format(module, e) + return ret + + if not ret['changes']: + ret['comment'] = "No updates to sync" + + return ret + + +def sync_all(name, **kwargs): + ''' + Performs the same task as saltutil.sync_all module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_all: + - refresh: True + ''' + ret = {'name': name, 'changes': {}, 'result': True, 'comment': ''} + + if __opts__['test']: + ret['result'] = None + ret['comment'] = "saltutil.sync_all would have been run" + return ret + + try: + sync_status = __salt__['saltutil.sync_all'](**kwargs) + for key, value in sync_status.items(): + if value: + ret['changes'][key] = value + ret['comment'] = "Sync performed" + except Exception as e: + log.error("Failed to run saltutil.sync_all: %s", e) + ret['result'] = False + ret['comment'] = "Failed to run sync_all: {0}".format(e) + return ret + + if not ret['changes']: + ret['comment'] = "No updates to sync" + + return ret + + +def sync_beacons(name, **kwargs): + ''' + Performs the same task as saltutil.sync_beacons module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_beacons: + - refresh: True + ''' + return _sync_single(name, "beacons", **kwargs) + + +def sync_clouds(name, **kwargs): + ''' + Performs the same task as saltutil.sync_clouds module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_clouds: + - refresh: True + ''' + return _sync_single(name, "clouds", **kwargs) + + +def sync_engines(name, **kwargs): + ''' + Performs the same task as saltutil.sync_engines module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_engines: + - refresh: True + ''' + return _sync_single(name, "engines", **kwargs) + + +def sync_grains(name, **kwargs): + ''' + Performs the same task as saltutil.sync_grains module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_grains: + - refresh: True + ''' + return _sync_single(name, "grains", **kwargs) + + +def sync_log_handlers(name, **kwargs): + ''' + Performs the same task as saltutil.sync_log_handlers module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_log_handlers: + - refresh: True + ''' + return _sync_single(name, "log_handlers", **kwargs) + + +def sync_modules(name, **kwargs): + ''' + Performs the same task as saltutil.sync_modules module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_modules: + - refresh: True + ''' + return _sync_single(name, "modules", **kwargs) + + +def sync_output(name, **kwargs): + ''' + Performs the same task as saltutil.sync_output module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_output: + - refresh: True + ''' + return _sync_single(name, "output", **kwargs) + + +def sync_outputters(name, **kwargs): + ''' + Performs the same task as saltutil.sync_outputters module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_outputters: + - refresh: True + ''' + return _sync_single(name, "outputters", **kwargs) + + +def sync_pillar(name, **kwargs): + ''' + Performs the same task as saltutil.sync_pillar module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_pillar: + - refresh: True + ''' + return _sync_single(name, "pillar", **kwargs) + + +def sync_proxymodules(name, **kwargs): + ''' + Performs the same task as saltutil.sync_proxymodules module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_proxymodules: + - refresh: True + ''' + return _sync_single(name, "proxymodules", **kwargs) + + +def sync_renderers(name, **kwargs): + ''' + Performs the same task as saltutil.sync_renderers module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_renderers: + - refresh: True + ''' + return _sync_single(name, "renderers", **kwargs) + + +def sync_returners(name, **kwargs): + ''' + Performs the same task as saltutil.sync_returners module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_returners: + - refresh: True + ''' + return _sync_single(name, "returners", **kwargs) + + +def sync_sdb(name, **kwargs): + ''' + Performs the same task as saltutil.sync_sdb module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_sdb: + - refresh: True + ''' + return _sync_single(name, "sdb", **kwargs) + + +def sync_states(name, **kwargs): + ''' + Performs the same task as saltutil.sync_states module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_states: + - refresh: True + ''' + return _sync_single(name, "states", **kwargs) + + +def sync_thorium(name, **kwargs): + ''' + Performs the same task as saltutil.sync_thorium module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_thorium: + - refresh: True + ''' + return _sync_single(name, "thorium", **kwargs) + + +def sync_utils(name, **kwargs): + ''' + Performs the same task as saltutil.sync_utils module + See :mod:`saltutil module for full list of options <salt.modules.saltutil>` + + .. code-block:: yaml + + sync_everything: + saltutil.sync_utils: + - refresh: True + ''' + return _sync_single(name, "utils", **kwargs) diff --git a/tests/unit/states/test_saltutil.py b/tests/unit/states/test_saltutil.py new file mode 100644 index 0000000000000000000000000000000000000000..707201e9e2d3c285ed497e7f497158907a1834eb --- /dev/null +++ b/tests/unit/states/test_saltutil.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +''' + Tests for the saltutil state +''' +# Import Python libs +from __future__ import absolute_import, print_function, unicode_literals + +# Import Salt Testing Libs +from tests.support.mixins import LoaderModuleMockMixin +from tests.support.unit import skipIf, TestCase +from tests.support.mock import ( + NO_MOCK, + NO_MOCK_REASON, + MagicMock, + patch +) + +# Import Salt Libs +import salt.states.saltutil as saltutil + + +@skipIf(NO_MOCK, NO_MOCK_REASON) +class Saltutil(TestCase, LoaderModuleMockMixin): + ''' + Test cases for salt.states.saltutil + ''' + def setup_loader_modules(self): + return {saltutil: {'__opts__': {'test': False}}} + + def test_saltutil_sync_all_nochange(self): + sync_output = { + "clouds": [], + "engines": [], + "grains": [], + "beacons": [], + "utils": [], + "returners": [], + "modules": [], + "renderers": [], + "log_handlers": [], + "thorium": [], + "states": [], + "sdb": [], + "proxymodules": [], + "output": [], + "pillar": [] + } + state_id = 'somename' + state_result = {'changes': {}, + 'comment': 'No updates to sync', + 'name': 'somename', + 'result': True + } + + mock_moduleout = MagicMock(return_value=sync_output) + with patch.dict(saltutil.__salt__, {'saltutil.sync_all': mock_moduleout}): + result = saltutil.sync_all(state_id, refresh=True) + self.assertEqual(result, state_result) + + def test_saltutil_sync_all_test(self): + sync_output = { + "clouds": [], + "engines": [], + "grains": [], + "beacons": [], + "utils": [], + "returners": [], + "modules": [], + "renderers": [], + "log_handlers": [], + "thorium": [], + "states": [], + "sdb": [], + "proxymodules": [], + "output": [], + "pillar": [] + } + state_id = 'somename' + state_result = {'changes': {}, + 'comment': 'saltutil.sync_all would have been run', + 'name': 'somename', + 'result': None + } + + mock_moduleout = MagicMock(return_value=sync_output) + with patch.dict(saltutil.__salt__, {'saltutil.sync_all': mock_moduleout}): + with patch.dict(saltutil.__opts__, {"test": True}): + result = saltutil.sync_all(state_id, refresh=True) + self.assertEqual(result, state_result) + + + def test_saltutil_sync_all_change(self): + sync_output = { + "clouds": [], + "engines": [], + "grains": [], + "beacons": [], + "utils": [], + "returners": [], + "modules": ["modules.file"], + "renderers": [], + "log_handlers": [], + "thorium": [], + "states": ["states.saltutil", "states.ssh_auth"], + "sdb": [], + "proxymodules": [], + "output": [], + "pillar": [] + } + state_id = 'somename' + state_result = {'changes': {'modules': ['modules.file'], + 'states': ['states.saltutil', 'states.ssh_auth']}, + 'comment': 'Sync performed', + 'name': 'somename', + 'result': True + } + + mock_moduleout = MagicMock(return_value=sync_output) + with patch.dict(saltutil.__salt__, {'saltutil.sync_all': mock_moduleout}): + result = saltutil.sync_all(state_id, refresh=True) + self.assertEqual(result, state_result) -- 2.23.0 ++++++ fix-load-cached-grain-osrelease_info.patch ++++++ >From 14f7acde30ea99abed535ab9491e9881ce609fdf Mon Sep 17 00:00:00 2001 From: Sergey Yurchik <srg91....@gmail.com> Date: Fri, 10 Jan 2020 12:19:54 +0300 Subject: [PATCH] Fix load cached grain "osrelease_info" Before fix the module `loader._load_cached_grains` loaded `osrelease_info` grain as list. But everythere it expects `tuple`. Now we force `osrelease_info` type and it works as expected. Fixes #54908 Sanitize grains loaded from roster_grains.json Ensure _format_cached_grains is called on state.pkg test --- salt/loader.py | 13 ++++++++++++- salt/modules/state.py | 3 ++- tests/unit/modules/test_state.py | 4 +++- tests/unit/test_loader.py | 28 ++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/salt/loader.py b/salt/loader.py index 26b44de511d77dd498a1db655a44144f6e9fbf0a..984d80758ba8bd733a211f42d89e2d4e4fb25341 100644 --- a/salt/loader.py +++ b/salt/loader.py @@ -689,6 +689,17 @@ def grain_funcs(opts, proxy=None): return ret +def _format_cached_grains(cached_grains): + """ + Returns cached grains with fixed types, like tuples. + """ + if cached_grains.get('osrelease_info'): + osrelease_info = cached_grains['osrelease_info'] + if isinstance(osrelease_info, list): + cached_grains['osrelease_info'] = tuple(osrelease_info) + return cached_grains + + def _load_cached_grains(opts, cfn): ''' Returns the grains cached in cfn, or None if the cache is too old or is @@ -721,7 +732,7 @@ def _load_cached_grains(opts, cfn): log.debug('Cached grains are empty, cache might be corrupted. Refreshing.') return None - return cached_grains + return _format_cached_grains(cached_grains) except (IOError, OSError): return None diff --git a/salt/modules/state.py b/salt/modules/state.py index a757e401d4f5c8fff33ad4b0f30f2882631fab80..197d69e1ff53e759ab268b9d562e6eb54f828e4c 100644 --- a/salt/modules/state.py +++ b/salt/modules/state.py @@ -42,6 +42,7 @@ import salt.defaults.exitcodes from salt.exceptions import CommandExecutionError, SaltInvocationError from salt.runners.state import orchestrate as _orchestrate from salt.utils.odict import OrderedDict +from salt.loader import _format_cached_grains # Import 3rd-party libs from salt.ext import six @@ -2177,7 +2178,7 @@ def pkg(pkg_path, roster_grains_json = os.path.join(root, 'roster_grains.json') if os.path.isfile(roster_grains_json): with salt.utils.files.fopen(roster_grains_json, 'r') as fp_: - roster_grains = salt.utils.json.load(fp_) + roster_grains = _format_cached_grains(salt.utils.json.load(fp_)) if os.path.isfile(roster_grains_json): popts['grains'] = roster_grains diff --git a/tests/unit/modules/test_state.py b/tests/unit/modules/test_state.py index 0d15458be0a9b187efc7b2963612ea4bb078918e..8fc90d33bf22bf37a9597ecd1c6ff7ad43a60b6d 100644 --- a/tests/unit/modules/test_state.py +++ b/tests/unit/modules/test_state.py @@ -1164,8 +1164,10 @@ class StateTestCase(TestCase, LoaderModuleMockMixin): MockTarFile.path = "" with patch('salt.utils.files.fopen', mock_open()), \ - patch.object(salt.utils.json, 'loads', mock_json_loads_true): + patch.object(salt.utils.json, 'loads', mock_json_loads_true), \ + patch.object(state, '_format_cached_grains', MagicMock()): self.assertEqual(state.pkg(tar_file, 0, "md5"), True) + state._format_cached_grains.assert_called_once() MockTarFile.path = "" if six.PY2: diff --git a/tests/unit/test_loader.py b/tests/unit/test_loader.py index 38dcb181090c61935835f14dd780bad2aa02d9e8..4c2c1b44af2d2931505ddcbb4339e087be88b4fc 100644 --- a/tests/unit/test_loader.py +++ b/tests/unit/test_loader.py @@ -1334,3 +1334,31 @@ class LazyLoaderOptimizationOrderTest(TestCase): basename = os.path.basename(filename) expected = 'lazyloadertest.py' if six.PY3 else 'lazyloadertest.pyc' assert basename == expected, basename + + +class LoaderLoadCachedGrainsTest(TestCase): + ''' + Test how the loader works with cached grains + ''' + + @classmethod + def setUpClass(cls): + cls.opts = salt.config.minion_config(None) + if not os.path.isdir(RUNTIME_VARS.TMP): + os.makedirs(RUNTIME_VARS.TMP) + + def setUp(self): + self.cache_dir = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP) + self.addCleanup(shutil.rmtree, self.cache_dir, ignore_errors=True) + + self.opts['cachedir'] = self.cache_dir + self.opts['grains_cache'] = True + self.opts['grains'] = salt.loader.grains(self.opts) + + def test_osrelease_info_has_correct_type(self): + ''' + Make sure osrelease_info is tuple after caching + ''' + grains = salt.loader.grains(self.opts) + osrelease_info = grains['osrelease_info'] + assert isinstance(osrelease_info, tuple), osrelease_info -- 2.23.0