# -*- coding: utf-8 -*- ''' test for pillar file_tree.py ''' # Import python libs from __future__ import absolute_import, print_function, unicode_literals import os import tempfile import shutil # Import Salt Testing libs from tests.support.mixins import LoaderModuleMockMixin from tests.support.unit import TestCase, skipIf from tests.support.mock import NO_MOCK, NO_MOCK_REASON, patch, MagicMock from tests.support.paths import TMP from tests.support.helpers import TestsLoggingHandler # Import Salt Libs import salt.utils.files import salt.utils.stringutils import salt.pillar.file_tree as file_tree MINION_ID = 'test-host' NODEGROUP_PATH = os.path.join('nodegroups', 'test-group', 'files') HOST_PATH = os.path.join('hosts', MINION_ID, 'files') BASE_PILLAR_CONTENT = {'files': {'hostfile': b'base', 'groupfile': b'base'}} DEV_PILLAR_CONTENT = {'files': {'hostfile': b'base', 'groupfile': b'dev2', 'hostfile1': b'dev1', 'groupfile1': b'dev1', 'hostfile2': b'dev2'}} PARENT_PILLAR_CONTENT = {'files': {'hostfile': b'base', 'groupfile': b'base', 'hostfile2': b'dev2'}} FILE_DATA = { os.path.join('base', HOST_PATH, 'hostfile'): 'base', os.path.join('dev1', HOST_PATH, 'hostfile1'): 'dev1', os.path.join('dev2', HOST_PATH, 'hostfile2'): 'dev2', os.path.join('base', NODEGROUP_PATH, 'groupfile'): 'base', os.path.join('dev1', NODEGROUP_PATH, 'groupfile1'): 'dev1', os.path.join('dev2', NODEGROUP_PATH, 'groupfile'): 'dev2' # test merging } _CHECK_MINIONS_RETURN = {'minions': [MINION_ID], 'missing': []} @skipIf(NO_MOCK, NO_MOCK_REASON) class FileTreePillarTestCase(TestCase, LoaderModuleMockMixin): 'test file_tree pillar' maxDiff = None def setup_loader_modules(self): self.tmpdir = tempfile.mkdtemp(dir=TMP) self.addCleanup(shutil.rmtree, self.tmpdir) cachedir = os.path.join(self.tmpdir, 'cachedir') os.makedirs(os.path.join(cachedir, 'file_tree')) self.pillar_path = self._create_pillar_files() return { file_tree: { '__opts__': { 'cachedir': cachedir, 'pillar_roots': { 'base': [os.path.join(self.pillar_path, 'base')], 'dev': [os.path.join(self.pillar_path, 'base'), os.path.join(self.pillar_path, 'dev1'), os.path.join(self.pillar_path, 'dev2') ], 'parent': [os.path.join(self.pillar_path, 'base', 'sub1'), os.path.join(self.pillar_path, 'dev2', 'sub'), os.path.join(self.pillar_path, 'base', 'sub2'), ], }, 'pillarenv': 'base', 'nodegroups': {'test-group': [MINION_ID]}, 'optimization_order': [0, 1, 2], 'file_buffer_size': 262144, 'file_roots': {'base': '', 'dev': '', 'parent': ''}, 'extension_modules': '', 'renderer': 'yaml_jinja', 'renderer_blacklist': [], 'renderer_whitelist': [] } } } def _create_pillar_files(self): 'create files in tempdir' pillar_path = os.path.join(self.tmpdir, 'file_tree') for filename in FILE_DATA: filepath = os.path.join(pillar_path, filename) os.makedirs(os.path.dirname(filepath)) with salt.utils.files.fopen(filepath, 'w') as data_file: data_file.write(salt.utils.stringutils.to_str(FILE_DATA[filename])) return pillar_path def test_absolute_path(self): 'check file tree is imported correctly with an absolute path' absolute_path = os.path.join(self.pillar_path, 'base') with patch('salt.utils.minions.CkMinions.check_minions', MagicMock(return_value=_CHECK_MINIONS_RETURN)): mypillar = file_tree.ext_pillar(MINION_ID, None, absolute_path) self.assertEqual(BASE_PILLAR_CONTENT, mypillar) with patch.dict(file_tree.__opts__, {'pillarenv': 'dev'}): mypillar = file_tree.ext_pillar(MINION_ID, None, absolute_path) self.assertEqual(BASE_PILLAR_CONTENT, mypillar) def test_relative_path(self): 'check file tree is imported correctly with a relative path' with patch('salt.utils.minions.CkMinions.check_minions', MagicMock(return_value=_CHECK_MINIONS_RETURN)): mypillar = file_tree.ext_pillar(MINION_ID, None, '.') self.assertEqual(BASE_PILLAR_CONTENT, mypillar) with patch.dict(file_tree.__opts__, {'pillarenv': 'dev'}): mypillar = file_tree.ext_pillar(MINION_ID, None, '.') self.assertEqual(DEV_PILLAR_CONTENT, mypillar) def test_parent_path(self): 'check if file tree is merged correctly with a .. path' with patch('salt.utils.minions.CkMinions.check_minions', MagicMock(return_value=_CHECK_MINIONS_RETURN)): with patch.dict(file_tree.__opts__, {'pillarenv': 'parent'}): mypillar = file_tree.ext_pillar(MINION_ID, None, '..') self.assertEqual(PARENT_PILLAR_CONTENT, mypillar) def test_no_pillarenv(self): 'confirm that file_tree yells when pillarenv is missing for a relative path' with patch('salt.utils.minions.CkMinions.check_minions', MagicMock(return_value=_CHECK_MINIONS_RETURN)): with patch.dict(file_tree.__opts__, {'pillarenv': None}): with TestsLoggingHandler() as handler: mypillar = file_tree.ext_pillar(MINION_ID, None, '.') self.assertEqual({}, mypillar) for message in handler.messages: if message.startswith('ERROR:') and 'pillarenv is not set' in message: break else: raise AssertionError('Did not find error message')