salt/tests/unit/config/test_api.py
Erik Johnson 3184168365 Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.

A summary of the changes in this PR is as follows:

* Moves the following functions from `salt.utils` to new locations
  (including a deprecation warning if invoked from `salt.utils`):
  `to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
  `dequote`, `is_hex`, `is_bin_str`, `rand_string`,
  `contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
  `which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
  `is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
  `is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
  `is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
  `salt/utils/__init__.py` for better organization, so we can keep the
  deprecated ones separate from the ones yet to be deprecated as we
  continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
  unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
  import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
  accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
  such that it returns a string matching the passed size. Previously
  this function would get `size` bytes from `os.urandom()`,
  base64-encode it, and return the result, which would in most cases not
  be equal to the passed size.
2017-08-08 13:33:43 -05:00

134 lines
4.8 KiB
Python

# -*- coding: utf-8 -*-
'''
tests.unit.api_config_test
'''
# Import Python libs
from __future__ import absolute_import
# Import Salt Testing libs
from tests.support.unit import skipIf, TestCase
from tests.support.helpers import destructiveTest
from tests.support.mock import (
MagicMock,
NO_MOCK,
NO_MOCK_REASON,
patch
)
# Import Salt libs
import salt.config
import salt.utils.platform
MOCK_MASTER_DEFAULT_OPTS = {
'log_file': '/var/log/salt/master',
'pidfile': '/var/run/salt-master.pid',
'root_dir': '/'
}
if salt.utils.platform.is_windows():
MOCK_MASTER_DEFAULT_OPTS = {
'log_file': 'c:\\salt\\var\\log\\salt\\master',
'pidfile': 'c:\\salt\\var\\run\\salt-master.pid',
'root_dir': 'c:\\salt'
}
@skipIf(NO_MOCK, NO_MOCK_REASON)
class APIConfigTestCase(TestCase):
'''
TestCase for the api_config function in salt.config.__init__.py
'''
def setUp(self):
# Copy DEFAULT_API_OPTS to restore after the test
self.default_api_opts = salt.config.DEFAULT_API_OPTS.copy()
def tearDown(self):
# Reset DEFAULT_API_OPTS settings as to not interfere with other unit tests
salt.config.DEFAULT_API_OPTS = self.default_api_opts
def test_api_config_log_file_values(self):
'''
Tests the opts value of the 'log_file' after running through the
various default dict updates. 'log_file' should be updated to match
the DEFAULT_API_OPTS 'api_logfile' value.
'''
with patch('salt.config.client_config', MagicMock(return_value=MOCK_MASTER_DEFAULT_OPTS)):
expected = '/var/log/salt/api'
if salt.utils.platform.is_windows():
expected = 'c:\\salt\\var\\log\\salt\\api'
ret = salt.config.api_config('/some/fake/path')
self.assertEqual(ret['log_file'], expected)
def test_api_config_pidfile_values(self):
'''
Tests the opts value of the 'pidfile' after running through the
various default dict updates. 'pidfile' should be updated to match
the DEFAULT_API_OPTS 'api_pidfile' value.
'''
with patch('salt.config.client_config', MagicMock(return_value=MOCK_MASTER_DEFAULT_OPTS)):
expected = '/var/run/salt-api.pid'
if salt.utils.platform.is_windows():
expected = 'c:\\salt\\var\\run\\salt-api.pid'
ret = salt.config.api_config('/some/fake/path')
self.assertEqual(ret['pidfile'], expected)
@destructiveTest
def test_master_config_file_overrides_defaults(self):
'''
Tests the opts value of the api config values after running through the
various default dict updates that should be overridden by settings in
the user's master config file.
'''
foo_dir = '/foo/bar/baz'
hello_dir = '/hello/world'
if salt.utils.platform.is_windows():
foo_dir = 'c:\\foo\\bar\\baz'
hello_dir = 'c:\\hello\\world'
mock_master_config = {
'api_pidfile': foo_dir,
'api_logfile': hello_dir,
'rest_timeout': 5
}
mock_master_config.update(MOCK_MASTER_DEFAULT_OPTS.copy())
with patch('salt.config.client_config',
MagicMock(return_value=mock_master_config)):
ret = salt.config.api_config('/some/fake/path')
self.assertEqual(ret['rest_timeout'], 5)
self.assertEqual(ret['api_pidfile'], foo_dir)
self.assertEqual(ret['pidfile'], foo_dir)
self.assertEqual(ret['api_logfile'], hello_dir)
self.assertEqual(ret['log_file'], hello_dir)
@destructiveTest
def test_api_config_prepend_root_dirs_return(self):
'''
Tests the opts value of the api_logfile, log_file, api_pidfile, and pidfile
when a custom root directory is used. This ensures that each of these
values is present in the list of opts keys that should have the root_dir
prepended when the api_config function returns the opts dictionary.
'''
mock_log = '/mock/root/var/log/salt/api'
mock_pid = '/mock/root/var/run/salt-api.pid'
mock_master_config = MOCK_MASTER_DEFAULT_OPTS.copy()
mock_master_config['root_dir'] = '/mock/root/'
if salt.utils.platform.is_windows():
mock_log = 'c:\\mock\\root\\var\\log\\salt\\api'
mock_pid = 'c:\\mock\\root\\var\\run\\salt-api.pid'
mock_master_config['root_dir'] = 'c:\\mock\\root'
with patch('salt.config.client_config',
MagicMock(return_value=mock_master_config)):
ret = salt.config.api_config('/some/fake/path')
self.assertEqual(ret['api_logfile'], mock_log)
self.assertEqual(ret['log_file'], mock_log)
self.assertEqual(ret['api_pidfile'], mock_pid)
self.assertEqual(ret['pidfile'], mock_pid)