mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
545 lines
18 KiB
Python
545 lines
18 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
:codeauthor: :email:`jmoney <justin@saltstack.com>`
|
|
'''
|
|
|
|
# Import Salt Libs
|
|
from salt.modules import cp
|
|
from salt.utils import templates
|
|
from salt.exceptions import CommandExecutionError
|
|
|
|
# Import Salt Testing Libs
|
|
from salttesting import skipIf, TestCase
|
|
from salttesting.helpers import ensure_in_syspath
|
|
from salttesting.mock import (
|
|
MagicMock,
|
|
mock_open,
|
|
patch,
|
|
NO_MOCK,
|
|
NO_MOCK_REASON
|
|
)
|
|
|
|
ensure_in_syspath('../../')
|
|
|
|
# Globals
|
|
cp.__salt__ = {}
|
|
cp.__opts__ = {}
|
|
cp.__pillar__ = {}
|
|
cp.__grains__ = {}
|
|
cp.__context__ = {}
|
|
|
|
|
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
class CpTestCase(TestCase):
|
|
'''
|
|
TestCase for salt.modules.cp module
|
|
'''
|
|
|
|
@patch('os.path.isdir', MagicMock(return_value=False))
|
|
def test_recv_return_unavailable(self):
|
|
'''
|
|
Test if recv returns unavailable.
|
|
'''
|
|
files = {'saltines': '/srv/salt/saltines',
|
|
'biscuits': '/srv/salt/biscuits'}
|
|
dest = '/srv/salt/cheese'
|
|
self.assertEqual(cp.recv(files, dest), 'Destination unavailable')
|
|
|
|
@patch('os.path.isdir', MagicMock(return_value=True))
|
|
def test_recv_return_success(self):
|
|
'''
|
|
Test if recv returns success.
|
|
'''
|
|
files = {'saltines': 'salt://saltines',
|
|
'biscuits': 'salt://biscuits'}
|
|
ret = {'/srv/salt/cheese/saltines': True,
|
|
'/srv/salt/cheese/biscuits': True}
|
|
dest = '/srv/salt/cheese'
|
|
file_data = 'Remember to keep your files well salted.'
|
|
with patch('salt.utils.fopen', mock_open(read_data=file_data)):
|
|
self.assertEqual(cp.recv(files, dest), ret)
|
|
|
|
def test__render_filenames_undefined_template(self):
|
|
'''
|
|
Test if _render_filenames fails upon getting a template not in
|
|
TEMPLATE_REGISTRY.
|
|
'''
|
|
path = '/srv/salt/saltines'
|
|
dest = '/srv/salt/cheese'
|
|
saltenv = 'base'
|
|
template = 'biscuits'
|
|
ret = (path, dest)
|
|
self.assertRaises(CommandExecutionError,
|
|
cp._render_filenames,
|
|
path, dest, saltenv, template)
|
|
|
|
def test__render_filenames_render_failed(self):
|
|
'''
|
|
Test if _render_filenames fails when template rendering fails.
|
|
'''
|
|
path = 'salt://saltines'
|
|
dest = '/srv/salt/cheese'
|
|
saltenv = 'base'
|
|
template = 'jinja'
|
|
file_data = 'Remember to keep your files well salted.'
|
|
mock_jinja = lambda *args, **kwargs: {'result': False,
|
|
'data': file_data}
|
|
with patch.dict(templates.TEMPLATE_REGISTRY,
|
|
{'jinja': mock_jinja}):
|
|
with patch('salt.utils.fopen', mock_open(read_data=file_data)):
|
|
self.assertRaises(CommandExecutionError,
|
|
cp._render_filenames,
|
|
path, dest, saltenv, template)
|
|
|
|
def test__render_filenames_success(self):
|
|
'''
|
|
Test if _render_filenames succeeds.
|
|
'''
|
|
path = 'salt://saltines'
|
|
dest = '/srv/salt/cheese'
|
|
saltenv = 'base'
|
|
template = 'jinja'
|
|
file_data = '/srv/salt/biscuits'
|
|
mock_jinja = lambda *args, **kwargs: {'result': True,
|
|
'data': file_data}
|
|
ret = (file_data, file_data) # salt.utils.fopen can only be mocked once
|
|
with patch.dict(templates.TEMPLATE_REGISTRY,
|
|
{'jinja': mock_jinja}):
|
|
with patch('salt.utils.fopen', mock_open(read_data=file_data)):
|
|
self.assertEqual(cp._render_filenames(
|
|
path, dest, saltenv, template), ret)
|
|
|
|
@patch('salt.modules.cp.hash_file', MagicMock(return_value=False))
|
|
def test_get_file_not_found(self):
|
|
'''
|
|
Test if get_file can't find the file.
|
|
'''
|
|
path = 'salt://saltines'
|
|
dest = '/srv/salt/cheese'
|
|
ret = ''
|
|
self.assertEqual(cp.get_file(path, dest), ret)
|
|
|
|
@patch('salt.modules.cp.hash_file', MagicMock(return_value=True))
|
|
def test_get_file_success(self):
|
|
'''
|
|
Test if get_file succeeds.
|
|
'''
|
|
path = 'salt://saltines'
|
|
dest = '/srv/salt/cheese'
|
|
saltenv = 'base'
|
|
ret = (path, dest, False, saltenv, None)
|
|
|
|
class MockFileClient(object):
|
|
def get_file(self, *args):
|
|
return args
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.get_file(path, dest), ret)
|
|
|
|
def test_get_template_success(self):
|
|
'''
|
|
Test if get_template succeeds.
|
|
'''
|
|
path = 'salt://saltines'
|
|
dest = '/srv/salt/cheese'
|
|
template = 'jinja'
|
|
saltenv = 'base'
|
|
ret = ((path, dest, template, False, saltenv),
|
|
{'grains': {}, 'opts': {}, 'pillar': {}, 'salt': {}})
|
|
|
|
class MockFileClient(object):
|
|
def get_template(self, *args, **kwargs):
|
|
return args, kwargs
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.get_template(path, dest), ret)
|
|
|
|
def test_get_dir_success(self):
|
|
'''
|
|
Test if get_template succeeds.
|
|
'''
|
|
path = 'salt://saltines'
|
|
dest = '/srv/salt/cheese'
|
|
saltenv = 'base'
|
|
ret = (path, dest, saltenv, None)
|
|
|
|
class MockFileClient(object):
|
|
def get_dir(self, *args):
|
|
return args
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
with patch('salt.modules.cp._render_filenames',
|
|
MagicMock(return_value=(path, dest))):
|
|
self.assertEqual(cp.get_dir(path, dest), ret)
|
|
|
|
def test_get_url_success(self):
|
|
'''
|
|
Test if get_url succeeds.
|
|
'''
|
|
path = 'salt://saltines'
|
|
dest = '/srv/salt/cheese'
|
|
saltenv = 'base'
|
|
ret = (path, dest, False, saltenv)
|
|
|
|
class MockFileClient(object):
|
|
def get_url(self, *args):
|
|
return args
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.get_url(path, dest), ret)
|
|
|
|
def test_get_file_str_success(self):
|
|
'''
|
|
Test if get_file_str succeeds.
|
|
'''
|
|
path = 'salt://saltines'
|
|
dest = '/srv/salt/cheese/saltines'
|
|
file_data = 'Remember to keep your files well salted.'
|
|
saltenv = 'base'
|
|
ret = file_data
|
|
with patch('salt.utils.fopen', mock_open(read_data=file_data)):
|
|
with patch('salt.modules.cp.cache_file',
|
|
MagicMock(return_value=dest)):
|
|
self.assertEqual(cp.get_file_str(path, dest), ret)
|
|
|
|
def test_cache_file_success(self):
|
|
'''
|
|
Test if cache_file succeeds.
|
|
'''
|
|
path = 'salt://saltines'
|
|
saltenv = 'base'
|
|
ret = path
|
|
|
|
class MockFileClient(object):
|
|
def cache_file(self, path, saltenv):
|
|
return path
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.cache_file(path), ret)
|
|
|
|
def test_cache_files_success(self):
|
|
'''
|
|
Test if cache_files succeeds.
|
|
'''
|
|
paths = ['salt://saltines', 'salt://biscuits']
|
|
saltenv = 'base'
|
|
ret = paths
|
|
|
|
class MockFileClient(object):
|
|
def cache_files(self, paths, saltenv):
|
|
return paths
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.cache_files(paths), ret)
|
|
|
|
def test_cache_dir_success(self):
|
|
'''
|
|
Test if cache_dir succeeds.
|
|
'''
|
|
path = 'saltk//cheese'
|
|
files = ['/srv/salt/cheese/saltines', '/srv/salt/cheese/biscuits']
|
|
saltenv = 'base'
|
|
ret = files
|
|
|
|
class MockFileClient(object):
|
|
def cache_dir(self, *args):
|
|
return files
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.cache_dir(files), ret)
|
|
|
|
def test_cache_master_success(self):
|
|
'''
|
|
Test if cache_master succeeds.
|
|
'''
|
|
path = 'saltk//cheese'
|
|
files = ['/srv/salt/cheese/saltines', '/srv/salt/cheese/biscuits']
|
|
saltenv = 'base'
|
|
ret = files
|
|
|
|
class MockFileClient(object):
|
|
def cache_master(self, saltenv):
|
|
return files
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.cache_master(), ret)
|
|
|
|
@patch('os.path.exists', MagicMock(return_value=False))
|
|
def test_cache_local_file_not_exists(self):
|
|
'''
|
|
Test if cache_local_file handles a nonexistent file.
|
|
'''
|
|
path = 'saltk//saltines'
|
|
ret = ''
|
|
|
|
self.assertEqual(cp.cache_local_file(path), ret)
|
|
|
|
@patch('os.path.exists', MagicMock(return_value=True))
|
|
def test_cache_local_file_already_cached(self):
|
|
'''
|
|
Test if cache_local_file handles an already cached file.
|
|
'''
|
|
path = 'saltk//saltines'
|
|
dest_file = '/srv/salt/cheese/saltines'
|
|
mock_hash = {'hsum': 'deadbeef'}
|
|
ret = dest_file
|
|
|
|
with patch('salt.modules.cp.hash_file',
|
|
MagicMock(return_value=mock_hash)):
|
|
with patch('salt.modules.cp.is_cached',
|
|
MagicMock(return_value=dest_file)):
|
|
self.assertEqual(cp.cache_local_file(path), ret)
|
|
|
|
@patch('os.path.exists', MagicMock(return_value=True))
|
|
def test_cache_local_file_success(self):
|
|
'''
|
|
Test if cache_local_file succeeds.
|
|
'''
|
|
path = 'saltk//saltines'
|
|
dest_file = '/srv/salt/cheese/saltines'
|
|
ret = dest_file
|
|
|
|
class MockFileClient(object):
|
|
def cache_local_file(self, path):
|
|
return dest_file
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch('salt.modules.cp.is_cached',
|
|
MagicMock(return_value=False)):
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.cache_local_file(path), ret)
|
|
|
|
def test_list_states_success(self):
|
|
'''
|
|
Test if list_states succeeds.
|
|
'''
|
|
states = ['cheesse.saltines', 'cheese.biscuits']
|
|
ret = states
|
|
|
|
class MockFileClient(object):
|
|
def list_states(self, saltenv):
|
|
return states
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.list_states(), ret)
|
|
|
|
def test_list_master_success(self):
|
|
'''
|
|
Test if list_master succeeds.
|
|
'''
|
|
files = ['cheesse/saltines.sls', 'cheese/biscuits.sls']
|
|
ret = files
|
|
|
|
class MockFileClient(object):
|
|
def file_list(self, saltenv, prefix):
|
|
return files
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.list_master(), ret)
|
|
|
|
def test_list_master_dirs_success(self):
|
|
'''
|
|
Test if list_master_dirs succeeds.
|
|
'''
|
|
dirs = ['cheesse', 'gravy']
|
|
ret = dirs
|
|
|
|
class MockFileClient(object):
|
|
def dir_list(self, saltenv, prefix):
|
|
return dirs
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.list_master_dirs(), ret)
|
|
|
|
def test_list_master_symlinks_success(self):
|
|
'''
|
|
Test if list_master_symlinks succeeds.
|
|
'''
|
|
symlinks = ['american_cheesse', 'vegan_gravy']
|
|
ret = symlinks
|
|
|
|
class MockFileClient(object):
|
|
def symlink_list(self, saltenv, prefix):
|
|
return symlinks
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.list_master_symlinks(), ret)
|
|
|
|
def test_is_cached_success(self):
|
|
'''
|
|
Test if is_cached succeeds.
|
|
'''
|
|
path = 'salt://saltines'
|
|
ret = path
|
|
|
|
class MockFileClient(object):
|
|
def is_cached(self, path, saltenv):
|
|
return path
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
self.assertEqual(cp.is_cached(path), ret)
|
|
|
|
def test_hash_file_success(self):
|
|
'''
|
|
Test if hash_file succeeds.
|
|
'''
|
|
path = 'salt://saltines'
|
|
mock_hash = {'hsum': 'deadbeef', 'htype': 'sha65536'}
|
|
ret = mock_hash
|
|
|
|
class MockFileClient(object):
|
|
def hash_file(self, path, saltenv):
|
|
return mock_hash
|
|
|
|
mock_file_client = MockFileClient()
|
|
with patch.dict(cp.__context__, {'cp.fileclient': mock_file_client}):
|
|
with patch('salt.modules.cp.hash_file',
|
|
MagicMock(return_value=mock_hash)):
|
|
self.assertEqual(cp.hash_file(path), ret)
|
|
|
|
def test_push_non_absolute_path(self):
|
|
'''
|
|
Test if push fails on a non absolute path.
|
|
'''
|
|
path = '../saltines'
|
|
ret = False
|
|
|
|
self.assertEqual(cp.push(path), ret)
|
|
|
|
@patch('os.path.isfile', MagicMock(return_value=False))
|
|
def test_push_non_file(self):
|
|
'''
|
|
Test if push fails on a non file.
|
|
'''
|
|
path = '/srv/salt/saltines'
|
|
ret = False
|
|
|
|
self.assertEqual(cp.push(path), ret)
|
|
|
|
@patch('os.path.isfile', MagicMock(return_value=True))
|
|
def test_push_failed(self):
|
|
'''
|
|
Test if push fails.
|
|
'''
|
|
path = '/srv/salt/saltines'
|
|
file_data = 'Remember to keep your files well salted.'
|
|
mock_buf_size = len(file_data)
|
|
mock_id = 'You don\'t need to see his identification.'
|
|
ret = None
|
|
from time import sleep
|
|
|
|
class MockChannel(object):
|
|
@staticmethod
|
|
def factory(__opts__):
|
|
return MockChannel()
|
|
|
|
def send(self, load):
|
|
return None
|
|
|
|
class MockAuth(object):
|
|
def gen_token(self, salt):
|
|
return 'token info'
|
|
|
|
def mock_auth_factory():
|
|
return MockAuth()
|
|
|
|
with patch('salt.transport.Channel', MockChannel):
|
|
with patch('salt.modules.cp._auth', mock_auth_factory):
|
|
with patch('salt.utils.fopen', mock_open(read_data=file_data)):
|
|
with patch.dict(cp.__opts__,
|
|
{'file_buffer_size': mock_buf_size,
|
|
'id': mock_id}):
|
|
self.assertEqual(cp.push(path), ret)
|
|
|
|
@patch('os.path.isfile', MagicMock(return_value=True))
|
|
def test_push_success(self):
|
|
'''
|
|
Test if push succeeds.
|
|
'''
|
|
path = '/srv/salt/saltines'
|
|
file_data = ''
|
|
mock_buf_size = len(file_data)
|
|
mock_id = 'You don\'t need to see his identification.'
|
|
ret = True
|
|
from time import sleep
|
|
|
|
class MockChannel(object):
|
|
@staticmethod
|
|
def factory(__opts__):
|
|
return MockChannel()
|
|
|
|
def send(self, load):
|
|
return 'channel info'
|
|
|
|
class MockAuth(object):
|
|
def gen_token(self, salt):
|
|
return 'token info'
|
|
|
|
def mock_auth_factory():
|
|
return MockAuth()
|
|
|
|
with patch('salt.transport.Channel', MockChannel):
|
|
with patch('salt.modules.cp._auth', mock_auth_factory):
|
|
with patch('salt.utils.fopen', mock_open(read_data=file_data)):
|
|
with patch.dict(cp.__opts__,
|
|
{'file_buffer_size': mock_buf_size,
|
|
'id': mock_id}):
|
|
self.assertEqual(cp.push(path), ret)
|
|
|
|
def test_push_dir_non_absolute_path(self):
|
|
'''
|
|
Test if push_dir fails on a non absolute path.
|
|
'''
|
|
path = '../saltines'
|
|
ret = False
|
|
|
|
self.assertEqual(cp.push_dir(path), ret)
|
|
|
|
@patch('os.path.isfile', MagicMock(return_value=True))
|
|
def test_push_dir_file_success(self):
|
|
'''
|
|
Test if push_dir succeeds on a file.
|
|
'''
|
|
path = '/srv/salt/saltines'
|
|
ret = True
|
|
|
|
with patch('salt.modules.cp.push', MagicMock(return_value=True)):
|
|
self.assertEqual(cp.push_dir(path), ret)
|
|
|
|
@patch('os.path.isfile', MagicMock(return_value=False))
|
|
def test_push_dir_success(self):
|
|
'''
|
|
Test if push_dir succeeds on a file.
|
|
'''
|
|
path = '/srv/salt/cheese'
|
|
# The tuple must be enclosed within another tuple since Mock/MagicMock
|
|
# will unpack its return_value if return_value is set to an iterable.
|
|
# This at least happens when Mock is mocking a function that is being
|
|
# returned into a generator context.
|
|
mock_walk_ret = (('/srv/salt/cheese',
|
|
[],
|
|
['saltines.sls', 'biscuits.sls']),)
|
|
ret = True
|
|
|
|
with patch('salt.modules.cp.push', MagicMock(return_value=True)):
|
|
with patch('os.walk', MagicMock(return_value=mock_walk_ret)):
|
|
self.assertEqual(cp.push_dir(path), ret)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
from integration import run_tests
|
|
run_tests(CpTestCase, needs_daemon=False)
|