diff --git a/lib/ansible/config/manager.py b/lib/ansible/config/manager.py index 6d711fa98be..603f2fc5d38 100644 --- a/lib/ansible/config/manager.py +++ b/lib/ansible/config/manager.py @@ -55,17 +55,25 @@ def ensure_type(value, value_type, origin=None): :arg value: The value to ensure correct typing of :kwarg value_type: The type of the value. This can be any of the following strings: :boolean: sets the value to a True or False value + :bool: Same as 'boolean' :integer: Sets the value to an integer or raises a ValueType error + :int: Same as 'integer' :float: Sets the value to a float or raises a ValueType error :list: Treats the value as a comma separated list. Split the value and return it as a python list. :none: Sets the value to None :path: Expands any environment variables and tilde's in the value. - :tmp_path: Create a unique temporary directory inside of the directory + :tmppath: Create a unique temporary directory inside of the directory specified by value and return its path. + :temppath: Same as 'tmppath' + :tmp: Same as 'tmppath' :pathlist: Treat the value as a typical PATH string. (On POSIX, this means colon separated strings.) Split the value and then expand each part for environment variables and tildes. + :pathspec: Treat the value as a PATH string. Expands any environment variables + tildes's in the value. + :str: Sets the value to string types. + :string: Same as 'str' ''' basedir = None @@ -125,7 +133,7 @@ def ensure_type(value, value_type, origin=None): # FIXME: see if this can live in utils/path def resolve_path(path, basedir=None): - ''' resolve relative or 'varaible' paths ''' + ''' resolve relative or 'variable' paths ''' if '{{CWD}}' in path: # allow users to force CWD using 'magic' {{CWD}} path = path.replace('{{CWD}}', os.getcwd()) diff --git a/test/units/config/test_manager.py b/test/units/config/test_manager.py index f3a4a904047..9072c62de94 100644 --- a/test/units/config/test_manager.py +++ b/test/units/config/test_manager.py @@ -1,13 +1,17 @@ +# -*- coding: utf-8 -*- +# Copyright: (c) 2017, Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + # Make coding more python3-ish from __future__ import (absolute_import, division, print_function) __metaclass__ = type import os import os.path +import pytest -from units.compat import unittest - -from ansible.config.manager import ConfigManager, Setting, ensure_type, resolve_path, find_ini_config_file +from ansible.config.manager import ConfigManager, Setting, ensure_type, resolve_path, get_config_type +from ansible.errors import AnsibleOptionsError, AnsibleError curdir = os.path.dirname(__file__) cfg_file = os.path.join(curdir, 'test.cfg') @@ -23,88 +27,90 @@ expected_ini = {'CONFIG_FILE': Setting(name='CONFIG_FILE', value=cfg_file, origi 'config_entry_multi_deprecated_source': Setting(name='config_entry_multi_deprecated_source', value=u'morefromini', origin=cfg_file, type='string')} - -class TestConfigData(unittest.TestCase): - - def setUp(self): - self.manager = ConfigManager(cfg_file, os.path.join(curdir, 'test.yml')) - - def tearDown(self): - self.manager = None +ensure_test_data = [ + ('a,b', 'list', list), + (['a', 'b'], 'list', list), + ('y', 'bool', bool), + ('yes', 'bool', bool), + ('on', 'bool', bool), + ('1', 'bool', bool), + ('true', 'bool', bool), + ('t', 'bool', bool), + (1, 'bool', bool), + (1.0, 'bool', bool), + (True, 'bool', bool), + ('n', 'bool', bool), + ('no', 'bool', bool), + ('off', 'bool', bool), + ('0', 'bool', bool), + ('false', 'bool', bool), + ('f', 'bool', bool), + (0, 'bool', bool), + (0.0, 'bool', bool), + (False, 'bool', bool), + ('10', 'int', int), + (20, 'int', int), + ('0.10', 'float', float), + (0.2, 'float', float), + ('/tmp/test.yml', 'pathspec', list), + ('/tmp/test.yml,/home/test2.yml', 'pathlist', list), + ('a', 'str', str), + ('a', 'string', str), + ('None', 'none', type(None)) +] + + +class TestConfigManager: + @classmethod + def setup_class(cls): + cls.manager = ConfigManager(cfg_file, os.path.join(curdir, 'test.yml')) + + @classmethod + def teardown_class(cls): + cls.manager = None def test_initial_load(self): - self.assertEquals(self.manager.data._global_settings, expected_ini) - - def test_ensure_type_list(self): - self.assertIsInstance(ensure_type('a,b', 'list'), list) - self.assertIsInstance(ensure_type(['a', 'b'], 'list'), list) - - def test_ensure_type_bool(self): - self.assertIsInstance(ensure_type('yes', 'bool'), bool) - self.assertIsInstance(ensure_type(True, 'bool'), bool) - - def test_ensure_type_int(self): - self.assertIsInstance(ensure_type('10', 'int'), int) - self.assertIsInstance(ensure_type(20, 'int'), int) + assert self.manager.data._global_settings == expected_ini - def test_ensure_type_float(self): - self.assertIsInstance(ensure_type('0.10', 'float'), float) - self.assertIsInstance(ensure_type(0.2, 'float'), float) + @pytest.mark.parametrize("value, expected_type, python_type", ensure_test_data) + def test_ensure_type(self, value, expected_type, python_type): + assert isinstance(ensure_type(value, expected_type), python_type) def test_resolve_path(self): - self.assertEquals(os.path.join(curdir, 'test.yml'), resolve_path('./test.yml', cfg_file)) + assert os.path.join(curdir, 'test.yml') == resolve_path('./test.yml', cfg_file) def test_resolve_path_cwd(self): - self.assertEquals(os.path.join(os.getcwd(), 'test.yml'), resolve_path('{{CWD}}/test.yml')) - self.assertEquals(os.path.join(os.getcwd(), 'test.yml'), resolve_path('./test.yml')) - - def test_get_config_dest(self): - pass + assert os.path.join(os.getcwd(), 'test.yml') == resolve_path('{{CWD}}/test.yml') + assert os.path.join(os.getcwd(), 'test.yml') == resolve_path('./test.yml') def test_value_and_origin_from_ini(self): - self.assertEquals(self.manager.get_config_value_and_origin('config_entry'), ('fromini', cfg_file)) + assert self.manager.get_config_value_and_origin('config_entry') == ('fromini', cfg_file) def test_value_from_ini(self): - self.assertEquals(self.manager.get_config_value('config_entry'), 'fromini') + assert self.manager.get_config_value('config_entry') == 'fromini' def test_value_and_origin_from_alt_ini(self): - self.assertEquals(self.manager.get_config_value_and_origin('config_entry', cfile=cfg_file2), ('fromini2', cfg_file2)) + assert self.manager.get_config_value_and_origin('config_entry', cfile=cfg_file2) == ('fromini2', cfg_file2) def test_value_from_alt_ini(self): - self.assertEquals(self.manager.get_config_value('config_entry', cfile=cfg_file2), 'fromini2') - - def test_value_and_origin_from_yaml(self): - pass - - def test_value_from_yaml(self): - pass - - def test_value_and_origin_from_alt_yaml(self): - pass - - def test_value_from_alt_yaml(self): - pass - - def test_config_type_bool(self): - pass - - def test_config_type_list(self): - pass - - def test_config_default(self): - pass + assert self.manager.get_config_value('config_entry', cfile=cfg_file2) == 'fromini2' - def test_deprecated_config(self): - pass + def test_config_types(self): + assert get_config_type('/tmp/ansible.ini') == 'ini' + assert get_config_type('/tmp/ansible.cfg') == 'ini' + assert get_config_type('/tmp/ansible.yaml') == 'yaml' + assert get_config_type('/tmp/ansible.yml') == 'yaml' - def test_deprecated_config_source(self): - pass + def test_config_types_negative(self): + with pytest.raises(AnsibleOptionsError) as exec_info: + get_config_type('/tmp/ansible.txt') + assert "Unsupported configuration file extension for" in str(exec_info.value) - def test_multi_precedence(self): - pass + def test_read_config_yaml_file(self): + assert isinstance(self.manager._read_config_yaml_file(os.path.join(curdir, 'test.yml')), dict) - def test_initialize_plugin_config(self): - pass + def test_read_config_yaml_file_negative(self): + with pytest.raises(AnsibleError) as exec_info: + self.manager._read_config_yaml_file(os.path.join(curdir, 'test_non_existent.yml')) - def test_update_config_data(self): - pass + assert "Missing base YAML definition file (bad install?)" in str(exec_info.value)