mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 09:23:56 +00:00
247 lines
9.8 KiB
Python
247 lines
9.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
:codeauthor: :email:`Rahul Handay <rahulha@saltstack.com>`
|
|
'''
|
|
|
|
# Import Python Libs
|
|
from __future__ import absolute_import, unicode_literals, print_function
|
|
import os
|
|
|
|
# Import Salt Testing Libs
|
|
from tests.support.mixins import LoaderModuleMockMixin
|
|
from tests.support.unit import TestCase, skipIf
|
|
from tests.support.mock import (
|
|
MagicMock,
|
|
patch,
|
|
NO_MOCK,
|
|
NO_MOCK_REASON
|
|
)
|
|
|
|
# Import Salt Libs
|
|
import salt.modules.win_path as win_path
|
|
import salt.utils.stringutils
|
|
|
|
|
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
class WinPathTestCase(TestCase, LoaderModuleMockMixin):
|
|
'''
|
|
Test cases for salt.modules.win_path
|
|
'''
|
|
def setup_loader_modules(self):
|
|
return {win_path: {}}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(WinPathTestCase, self).__init__(*args, **kwargs)
|
|
self.pathsep = str(';') # future lint: disable=blacklisted-function
|
|
|
|
def assert_call_matches(self, mock_obj, new_path):
|
|
mock_obj.assert_called_once_with(
|
|
win_path.HIVE,
|
|
win_path.KEY,
|
|
win_path.VNAME,
|
|
self.pathsep.join(new_path),
|
|
win_path.VTYPE
|
|
)
|
|
|
|
def assert_path_matches(self, env, new_path):
|
|
self.assertEqual(
|
|
env['PATH'],
|
|
salt.utils.stringutils.to_str(self.pathsep.join(new_path))
|
|
)
|
|
|
|
def test_get_path(self):
|
|
'''
|
|
Test to Returns the system path
|
|
'''
|
|
mock = MagicMock(return_value={'vdata': 'C:\\Salt'})
|
|
with patch.dict(win_path.__salt__, {'reg.read_value': mock}):
|
|
self.assertListEqual(win_path.get_path(), ['C:\\Salt'])
|
|
|
|
def test_exists(self):
|
|
'''
|
|
Test to check if the directory is configured
|
|
'''
|
|
get_mock = MagicMock(return_value=['C:\\Foo', 'C:\\Bar'])
|
|
with patch.object(win_path, 'get_path', get_mock):
|
|
# Ensure case insensitivity respected
|
|
self.assertTrue(win_path.exists('C:\\FOO'))
|
|
self.assertTrue(win_path.exists('c:\\foo'))
|
|
self.assertFalse(win_path.exists('c:\\mystuff'))
|
|
|
|
def test_add(self):
|
|
'''
|
|
Test to add the directory to the SYSTEM path
|
|
'''
|
|
orig_path = ('C:\\Foo', 'C:\\Bar')
|
|
|
|
def _env(path):
|
|
return {
|
|
str('PATH'): salt.utils.stringutils.to_str( # future lint: disable=blacklisted-function
|
|
self.pathsep.join(path)
|
|
)
|
|
}
|
|
|
|
def _run(name, index=None, retval=True, path=None):
|
|
if path is None:
|
|
path = orig_path
|
|
env = _env(path)
|
|
mock_get = MagicMock(return_value=list(path))
|
|
mock_set = MagicMock(return_value=retval)
|
|
with patch.object(win_path, 'PATHSEP', self.pathsep), \
|
|
patch.object(win_path, 'get_path', mock_get), \
|
|
patch.object(os, 'environ', env), \
|
|
patch.dict(win_path.__salt__, {'reg.set_value': mock_set}), \
|
|
patch.object(win_path, 'rehash', MagicMock(return_value=True)):
|
|
return win_path.add(name, index), env, mock_set
|
|
|
|
# Test a successful reg update
|
|
ret, env, mock_set = _run('c:\\salt', retval=True)
|
|
new_path = ('C:\\Foo', 'C:\\Bar', 'c:\\salt')
|
|
self.assertTrue(ret)
|
|
self.assert_call_matches(mock_set, new_path)
|
|
self.assert_path_matches(env, new_path)
|
|
|
|
# Test an unsuccessful reg update
|
|
ret, env, mock_set = _run('c:\\salt', retval=False)
|
|
new_path = ('C:\\Foo', 'C:\\Bar', 'c:\\salt')
|
|
self.assertFalse(ret)
|
|
self.assert_call_matches(mock_set, new_path)
|
|
# The local path should still have been modified even
|
|
# though reg.set_value failed.
|
|
self.assert_path_matches(env, new_path)
|
|
|
|
# Test adding with a custom index
|
|
ret, env, mock_set = _run('c:\\salt', index=1, retval=True)
|
|
new_path = ('C:\\Foo', 'c:\\salt', 'C:\\Bar')
|
|
self.assertTrue(ret)
|
|
self.assert_call_matches(mock_set, new_path)
|
|
self.assert_path_matches(env, new_path)
|
|
|
|
# Test adding path with a case-insensitive match already present, and
|
|
# no index provided. The path should remain unchanged and we should not
|
|
# update the registry.
|
|
ret, env, mock_set = _run('c:\\foo', retval=True)
|
|
self.assertTrue(ret)
|
|
mock_set.assert_not_called()
|
|
self.assert_path_matches(env, orig_path)
|
|
|
|
# Test adding path with a case-insensitive match already present, and a
|
|
# negative index provided which does not match the current index. The
|
|
# match should be removed, and the path should be added to the end of
|
|
# the list.
|
|
ret, env, mock_set = _run('c:\\foo', index=-1, retval=True)
|
|
new_path = ('C:\\Bar', 'c:\\foo')
|
|
self.assertTrue(ret)
|
|
self.assert_call_matches(mock_set, new_path)
|
|
self.assert_path_matches(env, new_path)
|
|
|
|
# Test adding path with a case-insensitive match already present, and a
|
|
# negative index provided which matches the current index. No changes
|
|
# should be made.
|
|
ret, env, mock_set = _run('c:\\foo', index=-2, retval=True)
|
|
self.assertTrue(ret)
|
|
mock_set.assert_not_called()
|
|
self.assert_path_matches(env, orig_path)
|
|
|
|
# Test adding path with a case-insensitive match already present, and a
|
|
# negative index provided which is larger than the size of the list. No
|
|
# changes should be made, since in these cases we assume an index of 0,
|
|
# and the case-insensitive match is also at index 0.
|
|
ret, env, mock_set = _run('c:\\foo', index=-5, retval=True)
|
|
self.assertTrue(ret)
|
|
mock_set.assert_not_called()
|
|
self.assert_path_matches(env, orig_path)
|
|
|
|
# Test adding path with a case-insensitive match already present, and a
|
|
# negative index provided which is larger than the size of the list.
|
|
# The match should be removed from its current location and inserted at
|
|
# the beginning, since when a negative index is larger than the list,
|
|
# we put it at the beginning of the list.
|
|
ret, env, mock_set = _run('c:\\bar', index=-5, retval=True)
|
|
new_path = ('c:\\bar', 'C:\\Foo')
|
|
self.assertTrue(ret)
|
|
self.assert_call_matches(mock_set, new_path)
|
|
self.assert_path_matches(env, new_path)
|
|
|
|
# Test adding path with a case-insensitive match already present, and a
|
|
# negative index provided which matches the current index. The path
|
|
# should remain unchanged and we should not update the registry.
|
|
ret, env, mock_set = _run('c:\\bar', index=-1, retval=True)
|
|
self.assertTrue(ret)
|
|
mock_set.assert_not_called()
|
|
self.assert_path_matches(env, orig_path)
|
|
|
|
# Test adding path with a case-insensitive match already present, and
|
|
# an index provided which does not match the current index, and is also
|
|
# larger than the size of the PATH list. The match should be removed,
|
|
# and the path should be added to the end of the list.
|
|
ret, env, mock_set = _run('c:\\foo', index=5, retval=True)
|
|
new_path = ('C:\\Bar', 'c:\\foo')
|
|
self.assertTrue(ret)
|
|
self.assert_call_matches(mock_set, new_path)
|
|
self.assert_path_matches(env, new_path)
|
|
|
|
def test_remove(self):
|
|
'''
|
|
Test win_path.remove
|
|
'''
|
|
orig_path = ('C:\\Foo', 'C:\\Bar', 'C:\\Baz')
|
|
|
|
def _env(path):
|
|
return {
|
|
str('PATH'): salt.utils.stringutils.to_str( # future lint: disable=blacklisted-function
|
|
self.pathsep.join(path)
|
|
)
|
|
}
|
|
|
|
def _run(name='c:\\salt', index=None, retval=True, path=None):
|
|
if path is None:
|
|
path = orig_path
|
|
env = _env(path)
|
|
mock_get = MagicMock(return_value=list(path))
|
|
mock_set = MagicMock(return_value=retval)
|
|
with patch.object(win_path, 'PATHSEP', self.pathsep), \
|
|
patch.object(win_path, 'get_path', mock_get), \
|
|
patch.object(os, 'environ', env), \
|
|
patch.dict(win_path.__salt__, {'reg.set_value': mock_set}), \
|
|
patch.object(win_path, 'rehash', MagicMock(return_value=True)):
|
|
return win_path.remove(name), env, mock_set
|
|
|
|
# Test a successful reg update
|
|
ret, env, mock_set = _run('C:\\Bar', retval=True)
|
|
new_path = ('C:\\Foo', 'C:\\Baz')
|
|
self.assertTrue(ret)
|
|
self.assert_call_matches(mock_set, new_path)
|
|
self.assert_path_matches(env, new_path)
|
|
|
|
# Test a successful reg update with a case-insensitive match
|
|
ret, env, mock_set = _run('c:\\bar', retval=True)
|
|
new_path = ('C:\\Foo', 'C:\\Baz')
|
|
self.assertTrue(ret)
|
|
self.assert_call_matches(mock_set, new_path)
|
|
self.assert_path_matches(env, new_path)
|
|
|
|
# Test a successful reg update with multiple case-insensitive matches.
|
|
# All matches should be removed.
|
|
old_path = orig_path + ('C:\\BAR',)
|
|
ret, env, mock_set = _run('c:\\bar', retval=True)
|
|
new_path = ('C:\\Foo', 'C:\\Baz')
|
|
self.assertTrue(ret)
|
|
self.assert_call_matches(mock_set, new_path)
|
|
self.assert_path_matches(env, new_path)
|
|
|
|
# Test an unsuccessful reg update
|
|
ret, env, mock_set = _run('c:\\bar', retval=False)
|
|
new_path = ('C:\\Foo', 'C:\\Baz')
|
|
self.assertFalse(ret)
|
|
self.assert_call_matches(mock_set, new_path)
|
|
# The local path should still have been modified even
|
|
# though reg.set_value failed.
|
|
self.assert_path_matches(env, new_path)
|
|
|
|
# Test when no match found
|
|
ret, env, mock_set = _run('C:\\NotThere', retval=True)
|
|
self.assertTrue(ret)
|
|
mock_set.assert_not_called()
|
|
self.assert_path_matches(env, orig_path)
|