win_exec: refactor PS exec runner (#45334)

* win_exec: refactor PS exec runner

* more changes for PSCore compatibility

* made some changes based on the recent review

* split up module exec scripts for smaller payload

* removed C# module support to focus on just error msg improvement

* cleaned up c# test classifier code
This commit is contained in:
Jordan Borean
2018-10-03 08:55:53 +10:00
committed by Matt Davis
parent aa2f3edb49
commit e972287c35
34 changed files with 2751 additions and 1676 deletions

View File

@@ -0,0 +1,40 @@
#!powershell
#Requires -Module Ansible.ModuleUtils.Legacy
$ErrorActionPreference = "Stop"
Function Assert-Equals($actual, $expected) {
if ($actual -cne $expected) {
$call_stack = (Get-PSCallStack)[1]
$error_msg = "AssertionError:`r`nActual: `"$actual`" != Expected: `"$expected`"`r`nLine: $($call_stack.ScriptLineNumber), Method: $($call_stack.Position.Text)"
Fail-Json -obj $result -message $error_msg
}
}
$result = @{
changed = $false
}
#ConvertFrom-AnsibleJso
$input_json = '{"string":"string","float":3.1415926,"dict":{"string":"string","int":1},"list":["entry 1","entry 2"],"null":null,"int":1}'
$actual = ConvertFrom-AnsibleJson -InputObject $input_json
Assert-Equals -actual $actual.GetType() -expected ([Hashtable])
Assert-Equals -actual $actual.string.GetType() -expected ([String])
Assert-Equals -actual $actual.string -expected "string"
Assert-Equals -actual $actual.int.GetType() -expected ([Int32])
Assert-Equals -actual $actual.int -expected 1
Assert-Equals -actual $actual.null -expected $null
Assert-Equals -actual $actual.float.GetType() -expected ([Decimal])
Assert-Equals -actual $actual.float -expected 3.1415926
Assert-Equals -actual $actual.list.GetType() -expected ([Object[]])
Assert-Equals -actual $actual.list.Count -expected 2
Assert-Equals -actual $actual.list[0] -expected "entry 1"
Assert-Equals -actual $actual.list[1] -expected "entry 2"
Assert-Equals -actual $actual.GetType() -expected ([Hashtable])
Assert-Equals -actual $actual.dict.string -expected "string"
Assert-Equals -actual $actual.dict.int -expected 1
$result.msg = "good"
Exit-Json -obj $result

View File

@@ -0,0 +1,58 @@
#!powershell
#Requires -Module Ansible.ModuleUtils.Legacy
$params = Parse-Args $args -supports_check_mode $true
$data = Get-AnsibleParam -obj $params -name "data" -type "str" -default "normal"
$result = @{
changed = $false
}
<#
This module tests various error events in PowerShell to verify our hidden trap
catches them all and outputs a pretty error message with a traceback to help
users debug the actual issue
normal - normal execution, no errors
fail - Calls Fail-Json like normal
throw - throws an exception
error - Write-Error with ErrorActionPreferenceStop
cmdlet_error - Calls a Cmdlet with an invalid error
dotnet_exception - Calls a .NET function that will throw an error
function_throw - Throws an exception in a function
proc_exit_fine - calls an executable with a non-zero exit code with Exit-Json
proc_exit_fail - calls an executable with a non-zero exit code with Fail-Json
#>
Function Test-ThrowException {
throw "exception in function"
}
if ($data -eq "normal") {
Exit-Json -obj $result
} elseif ($data -eq "fail") {
Fail-Json -obj $result -message "fail message"
} elseif ($data -eq "throw") {
throw [ArgumentException]"module is thrown"
} elseif ($data -eq "error") {
Write-Error -Message $data
} elseif ($data -eq "cmdlet_error") {
Get-Item -Path "fake:\path"
} elseif ($data -eq "dotnet_exception") {
[System.IO.Path]::GetFullPath($null)
} elseif ($data -eq "function_throw") {
Test-ThrowException
} elseif ($data -eq "proc_exit_fine") {
# verifies that if no error was actually fired and we have an output, we
# don't use the RC to validate if the module failed
&cmd.exe /c exit 2
Exit-Json -obj $result
} elseif ($data -eq "proc_exit_fail") {
&cmd.exe /c exit 2
Fail-Json -obj $result -message "proc_exit_fail"
}
# verify no exception were silently caught during our tests
Fail-Json -obj $result -message "end of module"

View File

@@ -1,4 +1,115 @@
---
- name: test normal module execution
test_fail:
register: normal
- name: assert test normal module execution
assert:
that:
- not normal is failed
- name: test fail module execution
test_fail:
data: fail
register: fail_module
ignore_errors: yes
- name: assert test fail module execution
assert:
that:
- fail_module is failed
- fail_module.msg == "fail message"
- not fail_module.exception is defined
- name: test module with exception thrown
test_fail:
data: throw
register: throw_module
ignore_errors: yes
- name: assert test module with exception thrown
assert:
that:
- throw_module is failed
- 'throw_module.msg == "Unhandled exception while executing module: module is thrown"'
- '"throw [ArgumentException]\"module is thrown\"" in throw_module.exception'
- name: test module with error msg
test_fail:
data: error
register: error_module
ignore_errors: yes
- name: assert test module with error msg
assert:
that:
- error_module is failed
- 'error_module.msg == "Unhandled exception while executing module: error"'
- '"Write-Error -Message $data" in error_module.exception'
- name: test module with cmdlet error
test_fail:
data: cmdlet_error
register: cmdlet_error
ignore_errors: yes
- name: assert test module with cmdlet error
assert:
that:
- cmdlet_error is failed
- 'cmdlet_error.msg == "Unhandled exception while executing module: Cannot find drive. A drive with the name ''fake'' does not exist."'
- '"Get-Item -Path \"fake:\\path\"" in cmdlet_error.exception'
- name: test module with .NET exception
test_fail:
data: dotnet_exception
register: dotnet_exception
ignore_errors: yes
- name: assert test module with .NET exception
assert:
that:
- dotnet_exception is failed
- 'dotnet_exception.msg == "Unhandled exception while executing module: Exception calling \"GetFullPath\" with \"1\" argument(s): \"The path is not of a legal form.\""'
- '"[System.IO.Path]::GetFullPath($null)" in dotnet_exception.exception'
- name: test module with function exception
test_fail:
data: function_throw
register: function_exception
ignore_errors: yes
- name: assert test module with function exception
assert:
that:
- function_exception is failed
- 'function_exception.msg == "Unhandled exception while executing module: exception in function"'
- '"throw \"exception in function\"" in function_exception.exception'
- '"at Test-ThrowException, <No file>: line" in function_exception.exception'
- name: test module with fail process but Exit-Json
test_fail:
data: proc_exit_fine
register: proc_exit_fine
- name: assert test module with fail process but Exit-Json
assert:
that:
- not proc_exit_fine is failed
- name: test module with fail process but Fail-Json
test_fail:
data: proc_exit_fail
register: proc_exit_fail
ignore_errors: yes
- name: assert test module with fail process but Fail-Json
assert:
that:
- proc_exit_fail is failed
- proc_exit_fail.msg == "proc_exit_fail"
- not proc_exit_fail.exception is defined
- name: test out invalid options
test_invalid_requires:
register: invalid_options
@@ -127,3 +238,13 @@
args:
executable: cmd.exe
when: become_test_username in profile_dir_out.stdout_lines[0]
- name: test common functions in exec
test_common_functions:
register: common_functions_res
- name: assert test common functions in exec
assert:
that:
- not common_functions_res is failed
- common_functions_res.msg == "good"