You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ansible/test/units/_internal/_powershell/test_script.py

137 lines
4.4 KiB

from __future__ import annotations
import pytest
from ansible._internal._powershell import _script
# print_argv is a binary that echoes back the argv it receives.
ENCODED_CMD_CASES = [
(
# print_argv {'foo'}
"'foo'",
[],
['-EncodedCommand', 'JwBmAG8AbwAnAA=='],
),
(
# print_argv {'foo'} -args 'simple', '_x005F_', ([char]::ConvertFromUtf32(0x1F3B5))
"'foo'",
['simple', '_x005F_', "\U0001F3B5"],
['-EncodedCommand', 'JwBmAG8AbwAnAA==', '-EncodedArguments', (
'PABPAGIAagBzACAAeABtAGwAbgBzAD0AIgBoAHQAdABwADoALwAvAHMAYwBoAGUAbQBhAHMALgBtAGkAYwByAG8AcwBvAGYAdAAuAGMAb'
'wBtAC8AcABvAHcAZQByAHMAaABlAGwAbAAvADIAMAAwADQALwAwADQAIgAgAFYAZQByAHMAaQBvAG4APQAiADEALgAxAC4AMAAuADEAIg'
'A+ADwATwBiAGoAIABSAGUAZgBJAGQAPQAiADAAIgA+ADwAVABOACAAUgBlAGYASQBkAD0AIgAwACIAPgA8AFQAPgBTAHkAcwB0AGUAbQA'
'uAEMAbwBsAGwAZQBjAHQAaQBvAG4AcwAuAEEAcgByAGEAeQBMAGkAcwB0ADwALwBUAD4APABUAD4AUwB5AHMAdABlAG0ALgBPAGIAagBl'
'AGMAdAA8AC8AVAA+ADwALwBUAE4APgA8AEwAUwBUAD4APABTAD4AcwBpAG0AcABsAGUAPAAvAFMAPgA8AFMAPgBfAHgAMAAwADUARgBfA'
'HgAMAAwADUARgBfADwALwBTAD4APABTAD4AXwB4AEQAOAAzAEMAXwBfAHgARABGAEIANQBfADwALwBTAD4APAAvAEwAUwBUAD4APAAvAE'
'8AYgBqAD4APAAvAE8AYgBqAHMAPgA='
)],
)
]
@pytest.mark.parametrize('value, expected', [
('foo', 'foo'),
('foo_bar', 'foo_bar'),
('foo-bar', 'foo-bar'),
('123', '123'),
(r'C:\temp\pwsh.exe', r'C:\temp\pwsh.exe'),
('C:/temp/pwsh.exe', 'C:/temp/pwsh.exe'),
('', "''"),
('foo bar', "'foo bar'"),
('@foo', "'@foo'"),
("foo'bar", "'foo''bar'"),
("foo\u2018bar", "'foo\u2018\u2018bar'"),
("foo\u2019bar", "'foo\u2019\u2019bar'"),
("foo\u201abar", "'foo\u201a\u201abar'"),
("foo\u201bbar", "'foo\u201b\u201bbar'"),
])
def test_quote_argument(value, expected):
actual = _script.quote_pwsh_argument(value)
assert actual == expected
def test_quote_argument_force():
actual = _script.quote_pwsh_argument('foo', force_quote=True)
assert actual == "'foo'"
@pytest.mark.parametrize('cmd, args, expected', ENCODED_CMD_CASES)
def test_build_encoded_command(cmd, args, expected):
actual = _script._get_encoded_arguments(cmd, args)
assert actual == expected
@pytest.mark.parametrize('expected_cmd, expected_args, cmd_args', ENCODED_CMD_CASES)
def test_parse_encoded_command(expected_cmd, expected_args, cmd_args):
actual_cmd, actual_args = _script.parse_encoded_cmdline(" ".join(cmd_args))
assert actual_cmd == expected_cmd
assert actual_args == expected_args
def test_parse_encoded_command_no_encoded_command():
actual = _script.parse_encoded_cmdline('pwsh -EncodedArguments YQA=')
assert actual is None
def test_parse_encoded_command_no_value():
actual = _script.parse_encoded_cmdline('pwsh -EncodedCommand')
assert actual is None
def test_parse_encoded_command_no_args():
actual_script, actual_args = _script.parse_encoded_cmdline('pwsh -EncodedCommand YQA= foo')
assert actual_script == 'a'
assert actual_args == []
def test_parse_encoded_command_quoted():
actual_script, actual_args = _script.parse_encoded_cmdline("pwsh '-EncodedCommand' YQA= foo")
assert actual_script == 'a'
assert actual_args == []
def test_parse_encoded_command_no_value_after_args():
actual = _script.parse_encoded_cmdline('pwsh -EncodedCommand YQA= -EncodedArguments')
assert actual is None
@pytest.mark.parametrize(
('cmd', 'args', 'expected'),
(
pytest.param(
'foo.exe',
None,
'foo.exe',
id='no-args-relative-path',
),
pytest.param(
r'C:\Program Files\foo.exe',
None,
r"& 'C:\Program Files\foo.exe'",
id='no-args-absolute-path',
),
pytest.param(
'foo.exe',
['simple', 'with space'],
"foo.exe simple 'with space'",
id='whitespace',
),
pytest.param(
'foo.exe',
["with 'single' quote"],
"foo.exe 'with ''single'' quote'",
id='single-quote',
),
pytest.param(
'C:/path with space/test',
['arg1', 'arg 2'],
"& 'C:/path with space/test' arg1 'arg 2'",
id='spaced-path',
),
),
)
def test_build_pwsh_cmd_statement(cmd, args, expected):
actual = _script.build_pwsh_cmd_statement(cmd, args)
assert actual == expected