Improve testing for Windows SSH and other connection plugins (#83834)

Expands the test matrix used for testing on Windows to cover the three
connection plugins we support for all the tasks. This change also
changes how raw commands are run over SSH to avoid starting a
`powershell.exe` process that was uneeded in the majority of cases used
in Ansible. This simplifies our code a bit more by removing extra
Windows specific actions in the ssh plugin and improves the efficiency
when running tasks.
pull/83873/head
Jordan Borean 3 months ago committed by GitHub
parent db04499f58
commit 9a5a9e48fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -68,9 +68,11 @@ stages:
nameFormat: Server {0} nameFormat: Server {0}
testFormat: windows/{0}/1 testFormat: windows/{0}/1
targets: targets:
- test: 2016 - test: 2016/winrm/http
- test: 2019 - test: 2019/winrm/https
- test: 2022 - test: 2022/winrm/https
- test: 2022/psrp/http
- test: 2022/ssh/key
- stage: Remote - stage: Remote
dependsOn: [] dependsOn: []
jobs: jobs:
@ -181,9 +183,11 @@ stages:
nameFormat: Server {0} nameFormat: Server {0}
testFormat: i/windows/{0} testFormat: i/windows/{0}
targets: targets:
- test: 2016 - test: 2016/winrm/http
- test: 2019 - test: 2019/winrm/https
- test: 2022 - test: 2022/winrm/https
- test: 2022/psrp/http
- test: 2022/ssh/key
- stage: Incidental - stage: Incidental
dependsOn: [] dependsOn: []
jobs: jobs:

@ -6,6 +6,8 @@ declare -a args
IFS='/:' read -ra args <<< "$1" IFS='/:' read -ra args <<< "$1"
version="${args[1]}" version="${args[1]}"
connection="${args[2]}"
connection_setting="${args[3]}"
target="shippable/windows/incidental/" target="shippable/windows/incidental/"
@ -26,11 +28,7 @@ if [ -s /tmp/windows.txt ] || [ "${CHANGED:+$CHANGED}" == "" ]; then
echo "Detected changes requiring integration tests specific to Windows:" echo "Detected changes requiring integration tests specific to Windows:"
cat /tmp/windows.txt cat /tmp/windows.txt
echo "Running Windows integration tests for multiple versions concurrently." echo "Running Windows integration tests for the version ${version}."
platforms=(
--windows "${version}"
)
else else
echo "No changes requiring integration tests specific to Windows were detected." echo "No changes requiring integration tests specific to Windows were detected."
echo "Running Windows integration tests for a single version only: ${single_version}" echo "Running Windows integration tests for a single version only: ${single_version}"
@ -39,14 +37,10 @@ else
echo "Skipping this job since it is for: ${version}" echo "Skipping this job since it is for: ${version}"
exit 0 exit 0
fi fi
platforms=(
--windows "${version}"
)
fi fi
# shellcheck disable=SC2086 # shellcheck disable=SC2086
ansible-test windows-integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \ ansible-test windows-integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \
"${platforms[@]}" \ --controller "docker:default,python=${python_default}" \
--docker default --python "${python_default}" \ --target "remote:windows/${version},connection=${connection}+${connection_setting},provider=${provider}" \
--remote-terminate always --remote-stage "${stage}" --remote-provider "${provider}" --remote-terminate always --remote-stage "${stage}"

@ -6,7 +6,9 @@ declare -a args
IFS='/:' read -ra args <<< "$1" IFS='/:' read -ra args <<< "$1"
version="${args[1]}" version="${args[1]}"
group="${args[2]}" connection="${args[2]}"
connection_setting="${args[3]}"
group="${args[4]}"
target="shippable/windows/group${group}/" target="shippable/windows/group${group}/"
@ -31,11 +33,7 @@ if [ -s /tmp/windows.txt ] || [ "${CHANGED:+$CHANGED}" == "" ]; then
echo "Detected changes requiring integration tests specific to Windows:" echo "Detected changes requiring integration tests specific to Windows:"
cat /tmp/windows.txt cat /tmp/windows.txt
echo "Running Windows integration tests for multiple versions concurrently." echo "Running Windows integration tests for the version ${version}."
platforms=(
--windows "${version}"
)
else else
echo "No changes requiring integration tests specific to Windows were detected." echo "No changes requiring integration tests specific to Windows were detected."
echo "Running Windows integration tests for a single version only: ${single_version}" echo "Running Windows integration tests for a single version only: ${single_version}"
@ -44,17 +42,13 @@ else
echo "Skipping this job since it is for: ${version}" echo "Skipping this job since it is for: ${version}"
exit 0 exit 0
fi fi
platforms=(
--windows "${version}"
)
fi fi
for version in "${python_versions[@]}"; do for py_version in "${python_versions[@]}"; do
changed_all_target="all" changed_all_target="all"
changed_all_mode="default" changed_all_mode="default"
if [ "${version}" == "${python_default}" ]; then if [ "${py_version}" == "${python_default}" ]; then
# smoketest tests # smoketest tests
if [ "${CHANGED}" ]; then if [ "${CHANGED}" ]; then
# with change detection enabled run tests for anything changed # with change detection enabled run tests for anything changed
@ -80,7 +74,7 @@ for version in "${python_versions[@]}"; do
fi fi
# terminate remote instances on the final python version tested # terminate remote instances on the final python version tested
if [ "${version}" = "${python_versions[-1]}" ]; then if [ "${py_version}" = "${python_versions[-1]}" ]; then
terminate="always" terminate="always"
else else
terminate="never" terminate="never"
@ -88,7 +82,8 @@ for version in "${python_versions[@]}"; do
# shellcheck disable=SC2086 # shellcheck disable=SC2086
ansible-test windows-integration --color -v --retry-on-error "${ci}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \ ansible-test windows-integration --color -v --retry-on-error "${ci}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \
"${platforms[@]}" --changed-all-target "${changed_all_target}" --changed-all-mode "${changed_all_mode}" \ --changed-all-target "${changed_all_target}" --changed-all-mode "${changed_all_mode}" \
--docker default --python "${version}" \ --controller "docker:default,python=${py_version}" \
--remote-terminate "${terminate}" --remote-stage "${stage}" --remote-provider "${provider}" --target "remote:windows/${version},connection=${connection}+${connection_setting},provider=${provider}" \
--remote-terminate "${terminate}" --remote-stage "${stage}"
done done

@ -0,0 +1,13 @@
breaking_changes:
- >-
Stopped wrapping all commands sent over SSH on a Windows target with a
``powershell.exe`` executable. This results in one less process being started
on each command for Windows to improve efficiency, simplify the code, and
make ``raw`` an actual raw command run with the default shell configured on
the Windows sshd settings. This should have no affect on most tasks except
for ``raw`` which now is not guaranteed to always be running in a PowerShell
shell and from having the console output codepage set to UTF-8. To avoid this
issue either swap to using ``ansible.windows.win_command``,
``ansible.windows.win_shell``, ``ansible.windows.win_powershell`` or manually
wrap the raw command with the shell commands needed to set the output console
encoding.

@ -116,12 +116,11 @@ Write-AnsibleLog "INFO - parsed become input, user: '$username', type: '$logon_t
# set to Stop and cannot be changed. Also need to split the payload from the wrapper to prevent potentially # set to Stop and cannot be changed. Also need to split the payload from the wrapper to prevent potentially
# sensitive content from being logged by the scriptblock logger. # sensitive content from being logged by the scriptblock logger.
$bootstrap_wrapper = { $bootstrap_wrapper = {
&chcp.com 65001 > $null [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
$exec_wrapper_str = [System.Console]::In.ReadToEnd() $ew = [System.Console]::In.ReadToEnd()
$split_parts = $exec_wrapper_str.Split(@("`0`0`0`0"), 2, [StringSplitOptions]::RemoveEmptyEntries) $split_parts = $ew.Split(@("`0`0`0`0"), 2, [StringSplitOptions]::RemoveEmptyEntries)
Set-Variable -Name json_raw -Value $split_parts[1] Set-Variable -Name json_raw -Value $split_parts[1]
$exec_wrapper = [ScriptBlock]::Create($split_parts[0]) &([ScriptBlock]::Create($split_parts[0]))
&$exec_wrapper
} }
$exec_command = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($bootstrap_wrapper.ToString())) $exec_command = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($bootstrap_wrapper.ToString()))
$lp_command_line = "powershell.exe -NonInteractive -NoProfile -ExecutionPolicy Bypass -EncodedCommand $exec_command" $lp_command_line = "powershell.exe -NonInteractive -NoProfile -ExecutionPolicy Bypass -EncodedCommand $exec_command"

@ -1,4 +1,4 @@
&chcp.com 65001 > $null try { [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding } catch { $null = $_ }
if ($PSVersionTable.PSVersion -lt [Version]"3.0") { if ($PSVersionTable.PSVersion -lt [Version]"3.0") {
'{"failed":true,"msg":"Ansible requires PowerShell v3.0 or newer"}' '{"failed":true,"msg":"Ansible requires PowerShell v3.0 or newer"}'
@ -9,5 +9,4 @@ $exec_wrapper_str = $input | Out-String
$split_parts = $exec_wrapper_str.Split(@("`0`0`0`0"), 2, [StringSplitOptions]::RemoveEmptyEntries) $split_parts = $exec_wrapper_str.Split(@("`0`0`0`0"), 2, [StringSplitOptions]::RemoveEmptyEntries)
If (-not $split_parts.Length -eq 2) { throw "invalid payload" } If (-not $split_parts.Length -eq 2) { throw "invalid payload" }
Set-Variable -Name json_raw -Value $split_parts[1] Set-Variable -Name json_raw -Value $split_parts[1]
$exec_wrapper = [ScriptBlock]::Create($split_parts[0]) & ([ScriptBlock]::Create($split_parts[0]))
&$exec_wrapper

@ -1306,14 +1306,6 @@ class Connection(ConnectionBase):
# prompt that will not occur # prompt that will not occur
sudoable = False sudoable = False
# Make sure our first command is to set the console encoding to
# utf-8, this must be done via chcp to get utf-8 (65001)
# union-attr ignores rely on internal powershell shell plugin details,
# this should be fixed at a future point in time.
cmd_parts = ["chcp.com", "65001", self._shell._SHELL_REDIRECT_ALLNULL, self._shell._SHELL_AND] # type: ignore[union-attr]
cmd_parts.extend(self._shell._encode_script(cmd, as_list=True, strict_mode=False, preserve_rc=False)) # type: ignore[union-attr]
cmd = ' '.join(cmd_parts)
# we can only use tty when we are not pipelining the modules. piping # we can only use tty when we are not pipelining the modules. piping
# data into /usr/bin/python inside a tty automatically invokes the # data into /usr/bin/python inside a tty automatically invokes the
# python interactive-mode but the modules are not compatible with the # python interactive-mode but the modules are not compatible with the

@ -100,6 +100,8 @@ class ShellModule(ShellBase):
# Family of shells this has. Must match the filename without extension # Family of shells this has. Must match the filename without extension
SHELL_FAMILY = 'powershell' SHELL_FAMILY = 'powershell'
# We try catch as some connection plugins don't have a console (PSRP).
_CONSOLE_ENCODING = "try { [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding } catch {}"
_SHELL_REDIRECT_ALLNULL = '> $null' _SHELL_REDIRECT_ALLNULL = '> $null'
_SHELL_AND = ';' _SHELL_AND = ';'
@ -157,13 +159,14 @@ class ShellModule(ShellBase):
if not basefile: if not basefile:
basefile = self.__class__._generate_temp_dir_name() basefile = self.__class__._generate_temp_dir_name()
basefile = self._escape(self._unquote(basefile)) basefile = self._escape(self._unquote(basefile))
basetmpdir = tmpdir if tmpdir else self.get_option('remote_tmp') basetmpdir = self._escape(tmpdir if tmpdir else self.get_option('remote_tmp'))
script = ''' script = f'''
$tmp_path = [System.Environment]::ExpandEnvironmentVariables('%s') {self._CONSOLE_ENCODING}
$tmp = New-Item -Type Directory -Path $tmp_path -Name '%s' $tmp_path = [System.Environment]::ExpandEnvironmentVariables('{basetmpdir}')
$tmp = New-Item -Type Directory -Path $tmp_path -Name '{basefile}'
Write-Output -InputObject $tmp.FullName Write-Output -InputObject $tmp.FullName
''' % (basetmpdir, basefile) '''
return self._encode_script(script.strip()) return self._encode_script(script.strip())
def expand_user(self, user_home_path, username=''): def expand_user(self, user_home_path, username=''):
@ -177,7 +180,7 @@ class ShellModule(ShellBase):
script = "Write-Output ((Get-Location).Path + '%s')" % self._escape(user_home_path[1:]) script = "Write-Output ((Get-Location).Path + '%s')" % self._escape(user_home_path[1:])
else: else:
script = "Write-Output '%s'" % self._escape(user_home_path) script = "Write-Output '%s'" % self._escape(user_home_path)
return self._encode_script(script) return self._encode_script(f"{self._CONSOLE_ENCODING}; {script}")
def exists(self, path): def exists(self, path):
path = self._escape(self._unquote(path)) path = self._escape(self._unquote(path))

@ -17,6 +17,7 @@
plugin_type="connection", plugin_type="connection",
) == "scp" ) == "scp"
}} }}
echo_string: 汉语
- name: set test filename - name: set test filename
set_fact: set_fact:
@ -25,12 +26,19 @@
### raw with unicode arg and output ### raw with unicode arg and output
- name: raw with unicode arg and output - name: raw with unicode arg and output
raw: echo 汉语 raw: "{{ echo_commands[action_prefix ~ ansible_connection ~ '_' ~ (ansible_shell_type|default(''))] | default(echo_commands['default']) }}"
vars:
# Windows over SSH does not have a way to set the console codepage to allow UTF-8. We need to
# wrap the commands we send to the remote host to get it working.
echo_commands:
win_ssh_powershell: '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; echo {{ echo_string }}'
win_ssh_cmd: 'powershell.exe -Command "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; echo {{ echo_string }}"'
default: echo {{ echo_string }}
register: command register: command
- name: check output of raw with unicode arg and output - name: check output of raw with unicode arg and output
assert: assert:
that: that:
- "'汉语' in command.stdout" - echo_string in command.stdout
- command is changed # as of 2.2, raw should default to changed: true for consistency w/ shell/command/script modules - command is changed # as of 2.2, raw should default to changed: true for consistency w/ shell/command/script modules
### copy local file with unicode filename and content ### copy local file with unicode filename and content

@ -25,7 +25,7 @@
that: that:
- "getmac_result.rc == 0" - "getmac_result.rc == 0"
- "getmac_result.stdout" - "getmac_result.stdout"
- "not getmac_result.stderr" - (ansible_connection == 'ssh') | ternary(getmac_result.stderr is defined, not getmac_result.stderr)
- "getmac_result is not failed" - "getmac_result is not failed"
- "getmac_result is changed" - "getmac_result is changed"
@ -39,7 +39,7 @@
- "ipconfig_result.rc == 0" - "ipconfig_result.rc == 0"
- "ipconfig_result.stdout" - "ipconfig_result.stdout"
- "'Physical Address' in ipconfig_result.stdout" - "'Physical Address' in ipconfig_result.stdout"
- "not ipconfig_result.stderr" - (ansible_connection == 'ssh') | ternary(ipconfig_result.stderr is defined, not ipconfig_result.stderr)
- "ipconfig_result is not failed" - "ipconfig_result is not failed"
- "ipconfig_result is changed" - "ipconfig_result is changed"
@ -80,7 +80,7 @@
that: that:
- "sleep_command.rc == 0" - "sleep_command.rc == 0"
- "not sleep_command.stdout" - "not sleep_command.stdout"
- "not sleep_command.stderr" - (ansible_connection == 'ssh') | ternary(sleep_command.stderr is defined, not sleep_command.stderr)
- "sleep_command is not failed" - "sleep_command is not failed"
- "sleep_command is changed" - "sleep_command is changed"
@ -93,11 +93,14 @@
that: that:
- "raw_result.stdout_lines[0] == 'wwe=raw'" - "raw_result.stdout_lines[0] == 'wwe=raw'"
# ssh cannot pre-set the codepage so we need to do it in the command.
- name: unicode tests for winrm - name: unicode tests for winrm
when: ansible_connection != 'psrp' # Write-Host does not work over PSRP when: ansible_connection != 'psrp' # Write-Host does not work over PSRP
block: block:
- name: run a raw command with unicode chars and quoted args (from https://github.com/ansible/ansible-modules-core/issues/1929) - name: run a raw command with unicode chars and quoted args (from https://github.com/ansible/ansible-modules-core/issues/1929)
raw: Write-Host --% icacls D:\somedir\ /grant "! ЗАО. Руководство":F raw: |
{{ (ansible_connection == 'ssh') | ternary("[Console]::OutputEncoding = [System.Text.Encoding]::UTF8", "") }}
Write-Host --% icacls D:\somedir\ /grant "! ЗАО. Руководство":F
register: raw_result2 register: raw_result2
- name: make sure raw passes command as-is and doesn't split/rejoin args - name: make sure raw passes command as-is and doesn't split/rejoin args

@ -38,7 +38,7 @@
- "test_script_result.rc == 0" - "test_script_result.rc == 0"
- "test_script_result.stdout" - "test_script_result.stdout"
- "'Woohoo' in test_script_result.stdout" - "'Woohoo' in test_script_result.stdout"
- "not test_script_result.stderr" - (ansible_connection == 'ssh') | ternary(test_script_result.stderr is defined, not test_script_result.stderr)
- "test_script_result is not failed" - "test_script_result is not failed"
- "test_script_result is changed" - "test_script_result is changed"
@ -54,7 +54,7 @@
- "test_script_with_args_result.stdout_lines[0] == '/this'" - "test_script_with_args_result.stdout_lines[0] == '/this'"
- "test_script_with_args_result.stdout_lines[1] == '/that'" - "test_script_with_args_result.stdout_lines[1] == '/that'"
- "test_script_with_args_result.stdout_lines[2] == '/Ӧther'" - "test_script_with_args_result.stdout_lines[2] == '/Ӧther'"
- "not test_script_with_args_result.stderr" - (ansible_connection == 'ssh') | ternary(test_script_with_args_result.stderr is defined, not test_script_with_args_result.stderr)
- "test_script_with_args_result is not failed" - "test_script_with_args_result is not failed"
- "test_script_with_args_result is changed" - "test_script_with_args_result is changed"
@ -71,7 +71,7 @@
assert: assert:
that: that:
- test_script_with_large_args_result.rc == 0 - test_script_with_large_args_result.rc == 0
- not test_script_with_large_args_result.stderr - (ansible_connection == 'ssh') | ternary(test_script_with_large_args_result.stderr is defined, not test_script_with_large_args_result.stderr)
- test_script_with_large_args_result is not failed - test_script_with_large_args_result is not failed
- test_script_with_large_args_result is changed - test_script_with_large_args_result is changed
@ -99,7 +99,7 @@
- "test_script_with_splatting_result.stdout_lines[0] == 'this'" - "test_script_with_splatting_result.stdout_lines[0] == 'this'"
- "test_script_with_splatting_result.stdout_lines[1] == test_win_script_value" - "test_script_with_splatting_result.stdout_lines[1] == test_win_script_value"
- "test_script_with_splatting_result.stdout_lines[2] == 'other'" - "test_script_with_splatting_result.stdout_lines[2] == 'other'"
- "not test_script_with_splatting_result.stderr" - (ansible_connection == 'ssh') | ternary(test_script_with_splatting_result.stderr is defined, not test_script_with_splatting_result.stderr)
- "test_script_with_splatting_result is not failed" - "test_script_with_splatting_result is not failed"
- "test_script_with_splatting_result is changed" - "test_script_with_splatting_result is changed"
@ -115,7 +115,7 @@
- "test_script_with_splatting2_result.stdout_lines[0] == 'THIS'" - "test_script_with_splatting2_result.stdout_lines[0] == 'THIS'"
- "test_script_with_splatting2_result.stdout_lines[1] == 'THAT'" - "test_script_with_splatting2_result.stdout_lines[1] == 'THAT'"
- "test_script_with_splatting2_result.stdout_lines[2] == 'OTHER'" - "test_script_with_splatting2_result.stdout_lines[2] == 'OTHER'"
- "not test_script_with_splatting2_result.stderr" - (ansible_connection == 'ssh') | ternary(test_script_with_splatting2_result.stderr is defined, not test_script_with_splatting2_result.stderr)
- "test_script_with_splatting2_result is not failed" - "test_script_with_splatting2_result is not failed"
- "test_script_with_splatting2_result is changed" - "test_script_with_splatting2_result is changed"
@ -148,7 +148,7 @@
that: that:
- "test_script_creates_file_result.rc == 0" - "test_script_creates_file_result.rc == 0"
- "not test_script_creates_file_result.stdout" - "not test_script_creates_file_result.stdout"
- "not test_script_creates_file_result.stderr" - (ansible_connection == 'ssh') | ternary(test_script_creates_file_result.stderr is defined, not test_script_creates_file_result.stderr)
- "test_script_creates_file_result is not failed" - "test_script_creates_file_result is not failed"
- "test_script_creates_file_result is changed" - "test_script_creates_file_result is changed"
@ -176,7 +176,7 @@
that: that:
- "test_script_removes_file_result.rc == 0" - "test_script_removes_file_result.rc == 0"
- "not test_script_removes_file_result.stdout" - "not test_script_removes_file_result.stdout"
- "not test_script_removes_file_result.stderr" - (ansible_connection == 'ssh') | ternary(test_script_removes_file_result.stderr is defined, not test_script_removes_file_result.stderr)
- "test_script_removes_file_result is not failed" - "test_script_removes_file_result is not failed"
- "test_script_removes_file_result is changed" - "test_script_removes_file_result is changed"
@ -205,7 +205,7 @@
- "test_batch_result.rc == 0" - "test_batch_result.rc == 0"
- "test_batch_result.stdout" - "test_batch_result.stdout"
- "'batch' in test_batch_result.stdout" - "'batch' in test_batch_result.stdout"
- "not test_batch_result.stderr" - (ansible_connection == 'ssh') | ternary(test_batch_result.stderr is defined, not test_batch_result.stderr)
- "test_batch_result is not failed" - "test_batch_result is not failed"
- "test_batch_result is changed" - "test_batch_result is changed"
@ -219,7 +219,7 @@
- "test_cmd_result.rc == 0" - "test_cmd_result.rc == 0"
- "test_cmd_result.stdout" - "test_cmd_result.stdout"
- "'cmd extension' in test_cmd_result.stdout" - "'cmd extension' in test_cmd_result.stdout"
- "not test_cmd_result.stderr" - (ansible_connection == 'ssh') | ternary(test_cmd_result.stderr is defined, not test_cmd_result.stderr)
- "test_cmd_result is not failed" - "test_cmd_result is not failed"
- "test_cmd_result is changed" - "test_cmd_result is changed"

@ -1,4 +1,5 @@
shippable/windows/group1 shippable/windows/group1
shippable/windows/minimal shippable/windows/minimal
shippable/windows/smoketest shippable/windows/smoketest
needs/target/setup_remote_tmp_dir
windows windows

@ -0,0 +1,2 @@
dependencies:
- setup_remote_tmp_dir

@ -85,3 +85,35 @@
ansible.windows.win_shell: echo "name=foo" ansible.windows.win_shell: echo "name=foo"
register: win_shell_collection_res register: win_shell_collection_res
failed_when: win_shell_collection_res.stdout | trim != 'name=foo' failed_when: win_shell_collection_res.stdout | trim != 'name=foo'
- name: set ping data fact
set_fact:
# FUTURE: Fix psrp so it can handle non-ASCII chars in a non-pipeline scenario
ping_data: '{{ (ansible_connection == "psrp") | ternary("test", "汉语") }}'
- name: run module with pipelining disabled
ansible.builtin.command:
cmd: >-
ansible windows
-m ansible.windows.win_ping
-a 'data={{ ping_data }}'
-i {{ '-i '.join(ansible_inventory_sources) }}
{{ '' if not ansible_verbosity else '-' ~ ('v' * ansible_verbosity) }}
-e ansible_remote_tmp='{{ remote_tmp_dir | regex_replace('\\', '\\\\') }}'
register: pipeline_disabled_res
delegate_to: localhost
environment:
ANSIBLE_KEEP_REMOTE_FILES: 'true'
ANSIBLE_NOCOLOR: 'true'
ANSIBLE_FORCE_COLOR: 'false'
- name: view temp files
ansible.windows.win_shell: (Get-Item '{{ remote_tmp_dir }}\ansible-tmp-*\*').Name
register: pipeline_disabled_files
- name: assert run module with pipelining disabled
assert:
that:
- >-
pipeline_disabled_res.stdout is search('\"ping\": \"' ~ ping_data ~ '\"')
- pipeline_disabled_files.stdout_lines == ["AnsiballZ_win_ping.ps1"]

Loading…
Cancel
Save