1# -*- coding: utf-8 -*- 2# Copyright (c) 2019 Ansible Project 3# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 5from __future__ import absolute_import, division, print_function 6__metaclass__ = type 7 8import pytest 9 10from ansible.module_utils.common.parameters import list_no_log_values 11 12 13@pytest.fixture 14def argument_spec(): 15 # Allow extra specs to be passed to the fixture, which will be added to the output 16 def _argument_spec(extra_opts=None): 17 spec = { 18 'secret': {'type': 'str', 'no_log': True}, 19 'other_secret': {'type': 'str', 'no_log': True}, 20 'state': {'type': 'str'}, 21 'value': {'type': 'int'}, 22 } 23 24 if extra_opts: 25 spec.update(extra_opts) 26 27 return spec 28 29 return _argument_spec 30 31 32@pytest.fixture 33def module_parameters(): 34 # Allow extra parameters to be passed to the fixture, which will be added to the output 35 def _module_parameters(extra_params=None): 36 params = { 37 'secret': 'under', 38 'other_secret': 'makeshift', 39 'state': 'present', 40 'value': 5, 41 } 42 43 if extra_params: 44 params.update(extra_params) 45 46 return params 47 48 return _module_parameters 49 50 51def test_list_no_log_values_no_secrets(module_parameters): 52 argument_spec = { 53 'other_secret': {'type': 'str', 'no_log': False}, 54 'state': {'type': 'str'}, 55 'value': {'type': 'int'}, 56 } 57 expected = set() 58 assert expected == list_no_log_values(argument_spec, module_parameters) 59 60 61def test_list_no_log_values(argument_spec, module_parameters): 62 expected = set(('under', 'makeshift')) 63 assert expected == list_no_log_values(argument_spec(), module_parameters()) 64 65 66@pytest.mark.parametrize('extra_params', [ 67 {'subopt1': 1}, 68 {'subopt1': 3.14159}, 69 {'subopt1': ['one', 'two']}, 70 {'subopt1': ('one', 'two')}, 71]) 72def test_list_no_log_values_invalid_suboptions(argument_spec, module_parameters, extra_params): 73 extra_opts = { 74 'subopt1': { 75 'type': 'dict', 76 'options': { 77 'sub_1_1': {}, 78 } 79 } 80 } 81 82 with pytest.raises(TypeError, match=r"(Value '.*?' in the sub parameter field '.*?' must by a dict, not '.*?')" 83 r"|(dictionary requested, could not parse JSON or key=value)"): 84 list_no_log_values(argument_spec(extra_opts), module_parameters(extra_params)) 85 86 87def test_list_no_log_values_suboptions(argument_spec, module_parameters): 88 extra_opts = { 89 'subopt1': { 90 'type': 'dict', 91 'options': { 92 'sub_1_1': {'no_log': True}, 93 'sub_1_2': {'type': 'list'}, 94 } 95 } 96 } 97 98 extra_params = { 99 'subopt1': { 100 'sub_1_1': 'bagel', 101 'sub_1_2': ['pebble'], 102 } 103 } 104 105 expected = set(('under', 'makeshift', 'bagel')) 106 assert expected == list_no_log_values(argument_spec(extra_opts), module_parameters(extra_params)) 107 108 109def test_list_no_log_values_sub_suboptions(argument_spec, module_parameters): 110 extra_opts = { 111 'sub_level_1': { 112 'type': 'dict', 113 'options': { 114 'l1_1': {'no_log': True}, 115 'l1_2': {}, 116 'l1_3': { 117 'type': 'dict', 118 'options': { 119 'l2_1': {'no_log': True}, 120 'l2_2': {}, 121 } 122 } 123 } 124 } 125 } 126 127 extra_params = { 128 'sub_level_1': { 129 'l1_1': 'saucy', 130 'l1_2': 'napped', 131 'l1_3': { 132 'l2_1': 'corporate', 133 'l2_2': 'tinsmith', 134 } 135 } 136 } 137 138 expected = set(('under', 'makeshift', 'saucy', 'corporate')) 139 assert expected == list_no_log_values(argument_spec(extra_opts), module_parameters(extra_params)) 140 141 142def test_list_no_log_values_suboptions_list(argument_spec, module_parameters): 143 extra_opts = { 144 'subopt1': { 145 'type': 'list', 146 'elements': 'dict', 147 'options': { 148 'sub_1_1': {'no_log': True}, 149 'sub_1_2': {}, 150 } 151 } 152 } 153 154 extra_params = { 155 'subopt1': [ 156 { 157 'sub_1_1': ['playroom', 'luxury'], 158 'sub_1_2': 'deuce', 159 }, 160 { 161 'sub_1_2': ['squishier', 'finished'], 162 } 163 ] 164 } 165 166 expected = set(('under', 'makeshift', 'playroom', 'luxury')) 167 assert expected == list_no_log_values(argument_spec(extra_opts), module_parameters(extra_params)) 168 169 170def test_list_no_log_values_sub_suboptions_list(argument_spec, module_parameters): 171 extra_opts = { 172 'subopt1': { 173 'type': 'list', 174 'elements': 'dict', 175 'options': { 176 'sub_1_1': {'no_log': True}, 177 'sub_1_2': {}, 178 'subopt2': { 179 'type': 'list', 180 'elements': 'dict', 181 'options': { 182 'sub_2_1': {'no_log': True, 'type': 'list'}, 183 'sub_2_2': {}, 184 } 185 } 186 } 187 } 188 } 189 190 extra_params = { 191 'subopt1': { 192 'sub_1_1': ['playroom', 'luxury'], 193 'sub_1_2': 'deuce', 194 'subopt2': [ 195 { 196 'sub_2_1': ['basis', 'gave'], 197 'sub_2_2': 'liquid', 198 }, 199 { 200 'sub_2_1': ['composure', 'thumping'] 201 }, 202 ] 203 } 204 } 205 206 expected = set(('under', 'makeshift', 'playroom', 'luxury', 'basis', 'gave', 'composure', 'thumping')) 207 assert expected == list_no_log_values(argument_spec(extra_opts), module_parameters(extra_params)) 208 209 210@pytest.mark.parametrize('extra_params, expected', ( 211 ({'subopt_dict': 'dict_subopt1=rekindle-scandal,dict_subopt2=subgroupavenge'}, ('rekindle-scandal',)), 212 ({'subopt_dict': 'dict_subopt1=aversion-mutable dict_subopt2=subgroupavenge'}, ('aversion-mutable',)), 213 ({'subopt_dict': ['dict_subopt1=blip-marine,dict_subopt2=subgroupavenge', 'dict_subopt1=tipping,dict_subopt2=hardening']}, ('blip-marine', 'tipping')), 214)) 215def test_string_suboptions_as_string(argument_spec, module_parameters, extra_params, expected): 216 extra_opts = { 217 'subopt_dict': { 218 'type': 'dict', 219 'options': { 220 'dict_subopt1': {'no_log': True}, 221 'dict_subopt2': {}, 222 }, 223 }, 224 } 225 226 result = set(('under', 'makeshift')) 227 result.update(expected) 228 assert result == list_no_log_values(argument_spec(extra_opts), module_parameters(extra_params)) 229