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 135
|
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
# Copyright 2017, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import pytest
from ansible.errors import AnsibleParserError
from ansible.parsing.mod_args import ModuleArgsParser
from ansible.utils.sentinel import Sentinel
class TestModArgsDwim:
# TODO: add tests that construct ModuleArgsParser with a task reference
# TODO: verify the AnsibleError raised on failure knows the task
# and the task knows the line numbers
INVALID_MULTIPLE_ACTIONS = (
({'action': 'shell echo hi', 'local_action': 'shell echo hi'}, "action and local_action are mutually exclusive"),
({'action': 'shell echo hi', 'shell': 'echo hi'}, "conflicting action statements: shell, shell"),
({'local_action': 'shell echo hi', 'shell': 'echo hi'}, "conflicting action statements: shell, shell"),
)
def _debug(self, mod, args, to):
print("RETURNED module = {0}".format(mod))
print(" args = {0}".format(args))
print(" to = {0}".format(to))
def test_basic_shell(self):
m = ModuleArgsParser(dict(shell='echo hi'))
mod, args, to = m.parse()
self._debug(mod, args, to)
assert mod == 'shell'
assert args == dict(
_raw_params='echo hi',
)
assert to is Sentinel
def test_basic_command(self):
m = ModuleArgsParser(dict(command='echo hi'))
mod, args, to = m.parse()
self._debug(mod, args, to)
assert mod == 'command'
assert args == dict(
_raw_params='echo hi',
)
assert to is Sentinel
def test_shell_with_modifiers(self):
m = ModuleArgsParser(dict(shell='/bin/foo creates=/tmp/baz removes=/tmp/bleep'))
mod, args, to = m.parse()
self._debug(mod, args, to)
assert mod == 'shell'
assert args == dict(
creates='/tmp/baz',
removes='/tmp/bleep',
_raw_params='/bin/foo',
)
assert to is Sentinel
def test_normal_usage(self):
m = ModuleArgsParser(dict(copy='src=a dest=b'))
mod, args, to = m.parse()
self._debug(mod, args, to)
assert mod, 'copy'
assert args, dict(src='a', dest='b')
assert to is Sentinel
def test_complex_args(self):
m = ModuleArgsParser(dict(copy=dict(src='a', dest='b')))
mod, args, to = m.parse()
self._debug(mod, args, to)
assert mod, 'copy'
assert args, dict(src='a', dest='b')
assert to is Sentinel
def test_action_with_complex(self):
m = ModuleArgsParser(dict(action=dict(module='copy', src='a', dest='b')))
mod, args, to = m.parse()
self._debug(mod, args, to)
assert mod == 'copy'
assert args == dict(src='a', dest='b')
assert to is Sentinel
def test_action_with_complex_and_complex_args(self):
m = ModuleArgsParser(dict(action=dict(module='copy', args=dict(src='a', dest='b'))))
mod, args, to = m.parse()
self._debug(mod, args, to)
assert mod == 'copy'
assert args == dict(src='a', dest='b')
assert to is Sentinel
def test_local_action_string(self):
m = ModuleArgsParser(dict(local_action='copy src=a dest=b'))
mod, args, delegate_to = m.parse()
self._debug(mod, args, delegate_to)
assert mod == 'copy'
assert args == dict(src='a', dest='b')
assert delegate_to == 'localhost'
@pytest.mark.parametrize("args_dict, msg", INVALID_MULTIPLE_ACTIONS)
def test_multiple_actions(self, args_dict, msg):
m = ModuleArgsParser(args_dict)
with pytest.raises(AnsibleParserError) as err:
m.parse()
assert err.value.args[0] == msg
@pytest.mark.usefixtures('collection_loader')
def test_multiple_actions_ping_shell(self):
args_dict = {'ping': 'data=hi', 'shell': 'echo hi'}
m = ModuleArgsParser(args_dict)
with pytest.raises(AnsibleParserError) as err:
m.parse()
assert err.value.args[0] == f'conflicting action statements: {", ".join(args_dict)}'
@pytest.mark.usefixtures('collection_loader')
def test_bogus_action(self):
args_dict = {'bogusaction': {}}
m = ModuleArgsParser(args_dict)
with pytest.raises(AnsibleParserError) as err:
m.parse()
assert err.value.args[0].startswith(f"couldn't resolve module/action '{next(iter(args_dict))}'")
|