summaryrefslogtreecommitdiffstats
path: root/test/units/module_utils/common/arg_spec/test_validate_invalid.py
blob: 7302e8aad4e49a19e96b442bf0e521d6aa6724d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# -*- coding: utf-8 -*-
# Copyright (c) 2021 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function
__metaclass__ = type

import pytest

from ansible.module_utils.common.arg_spec import ArgumentSpecValidator, ValidationResult
from ansible.module_utils.errors import AnsibleValidationErrorMultiple
from ansible.module_utils.six import PY2


# Each item is id, argument_spec, parameters, expected, unsupported parameters, error test string
INVALID_SPECS = [
    (
        'invalid-list',
        {'packages': {'type': 'list'}},
        {'packages': {'key': 'value'}},
        {'packages': {'key': 'value'}},
        set(),
        "unable to convert to list: <class 'dict'> cannot be converted to a list",
    ),
    (
        'invalid-dict',
        {'users': {'type': 'dict'}},
        {'users': ['one', 'two']},
        {'users': ['one', 'two']},
        set(),
        "unable to convert to dict: <class 'list'> cannot be converted to a dict",
    ),
    (
        'invalid-bool',
        {'bool': {'type': 'bool'}},
        {'bool': {'k': 'v'}},
        {'bool': {'k': 'v'}},
        set(),
        "unable to convert to bool: <class 'dict'> cannot be converted to a bool",
    ),
    (
        'invalid-float',
        {'float': {'type': 'float'}},
        {'float': 'hello'},
        {'float': 'hello'},
        set(),
        "unable to convert to float: <class 'str'> cannot be converted to a float",
    ),
    (
        'invalid-bytes',
        {'bytes': {'type': 'bytes'}},
        {'bytes': 'one'},
        {'bytes': 'one'},
        set(),
        "unable to convert to bytes: <class 'str'> cannot be converted to a Byte value",
    ),
    (
        'invalid-bits',
        {'bits': {'type': 'bits'}},
        {'bits': 'one'},
        {'bits': 'one'},
        set(),
        "unable to convert to bits: <class 'str'> cannot be converted to a Bit value",
    ),
    (
        'invalid-jsonargs',
        {'some_json': {'type': 'jsonarg'}},
        {'some_json': set()},
        {'some_json': set()},
        set(),
        "unable to convert to jsonarg: <class 'set'> cannot be converted to a json string",
    ),
    (
        'invalid-parameter',
        {'name': {}},
        {
            'badparam': '',
            'another': '',
        },
        {
            'name': None,
            'badparam': '',
            'another': '',
        },
        set(('another', 'badparam')),
        "another, badparam. Supported parameters include: name.",
    ),
    (
        'invalid-elements',
        {'numbers': {'type': 'list', 'elements': 'int'}},
        {'numbers': [55, 33, 34, {'key': 'value'}]},
        {'numbers': [55, 33, 34]},
        set(),
        "Elements value for option 'numbers' is of type <class 'dict'> and we were unable to convert to int: <class 'dict'> cannot be converted to an int"
    ),
    (
        'required',
        {'req': {'required': True}},
        {},
        {'req': None},
        set(),
        "missing required arguments: req"
    ),
    (
        'blank_values',
        {'ch_param': {'elements': 'str', 'type': 'list', 'choices': ['a', 'b']}},
        {'ch_param': ['']},
        {'ch_param': ['']},
        set(),
        "value of ch_param must be one or more of"
    )
]


@pytest.mark.parametrize(
    ('arg_spec', 'parameters', 'expected', 'unsupported', 'error'),
    (i[1:] for i in INVALID_SPECS),
    ids=[i[0] for i in INVALID_SPECS]
)
def test_invalid_spec(arg_spec, parameters, expected, unsupported, error):
    v = ArgumentSpecValidator(arg_spec)
    result = v.validate(parameters)

    with pytest.raises(AnsibleValidationErrorMultiple) as exc_info:
        raise result.errors

    if PY2:
        error = error.replace('class', 'type')

    assert isinstance(result, ValidationResult)
    assert error in exc_info.value.msg
    assert error in result.error_messages[0]
    assert result.unsupported_parameters == unsupported
    assert result.validated_parameters == expected