1 #!powershell
2 
3 #Requires -Module Ansible.ModuleUtils.Legacy
4 #Requires -Module Ansible.ModuleUtils.CommandUtil
5 
6 $ErrorActionPreference = 'Stop'
7 
8 $params = Parse-Args $args
9 $exe = Get-AnsibleParam -obj $params -name "exe" -type "path" -failifempty $true
10 
11 $result = @{
12     changed = $false
13 }
14 
15 $exe_directory = Split-Path -Path $exe -Parent
16 $exe_filename = Split-Path -Path $exe -Leaf
17 $test_name = $null
18 
Assert-Equals($actual, $expected)19 Function Assert-Equals($actual, $expected) {
20     if ($actual -cne $expected) {
21         Fail-Json -obj $result -message "Test $test_name failed`nActual: '$actual' != Expected: '$expected'"
22     }
23 }
24 
25 $test_name = "full exe path"
26 $actual = Run-Command -command "`"$exe`" arg1 arg2 `"arg 3`""
27 Assert-Equals -actual $actual.rc -expected 0
28 Assert-Equals -actual $actual.stdout -expected "arg1`r`narg2`r`narg 3`r`n"
29 Assert-Equals -actual $actual.stderr -expected ""
30 Assert-Equals -actual $actual.executable -expected $exe
31 
32 $test_name = "exe in special char dir"
33 $tmp_dir = Join-Path -Path $env:TEMP -ChildPath "ansible .ÅÑŚÌβŁÈ [$!@^&test(;)]"
34 try {
35     New-Item -Path $tmp_dir -ItemType Directory > $null
36     $exe_special = Join-Path $tmp_dir -ChildPath "PrintArgv.exe"
37     Copy-Item -LiteralPath $exe -Destination $exe_special
38     $actual = Run-Command -command "`"$exe_special`" arg1 arg2 `"arg 3`""
39 } finally {
40     Remove-Item -LiteralPath $tmp_dir -Force -Recurse
41 }
42 Assert-Equals -actual $actual.rc -expected 0
43 Assert-Equals -actual $actual.stdout -expected "arg1`r`narg2`r`narg 3`r`n"
44 Assert-Equals -actual $actual.stderr -expected ""
45 Assert-Equals -actual $actual.executable -expected $exe_special
46 
47 $test_name = "invalid exe path"
48 try {
49     $actual = Run-Command -command "C:\fakepath\$exe_filename arg1"
50     Fail-Json -obj $result -message "Test $test_name failed`nCommand should have thrown an exception"
51 } catch {
52     Assert-Equals -actual $_.Exception.Message -expected "Exception calling `"SearchPath`" with `"1`" argument(s): `"Could not find file 'C:\fakepath\$exe_filename'.`""
53 }
54 
55 $test_name = "exe in current folder"
56 $actual = Run-Command -command "$exe_filename arg1" -working_directory $exe_directory
57 Assert-Equals -actual $actual.rc -expected 0
58 Assert-Equals -actual $actual.stdout -expected "arg1`r`n"
59 Assert-Equals -actual $actual.stderr -expected ""
60 Assert-Equals -actual $actual.executable -expected $exe
61 
62 $test_name = "no working directory set"
63 $actual = Run-Command -command "cmd.exe /c cd"
64 Assert-Equals -actual $actual.rc -expected 0
65 Assert-Equals -actual $actual.stdout -expected "$($pwd.Path)`r`n"
66 Assert-Equals -actual $actual.stderr -expected ""
67 Assert-Equals -actual $actual.executable.ToUpper() -expected "$env:SystemRoot\System32\cmd.exe".ToUpper()
68 
69 $test_name = "working directory override"
70 $actual = Run-Command -command "cmd.exe /c cd" -working_directory $env:SystemRoot
71 Assert-Equals -actual $actual.rc -expected 0
72 Assert-Equals -actual $actual.stdout -expected "$env:SystemRoot`r`n"
73 Assert-Equals -actual $actual.stderr -expected ""
74 Assert-Equals -actual $actual.executable.ToUpper() -expected "$env:SystemRoot\System32\cmd.exe".ToUpper()
75 
76 $test_name = "working directory invalid path"
77 try {
78     $actual = Run-Command -command "doesn't matter" -working_directory "invalid path here"
79     Fail-Json -obj $result -message "Test $test_name failed`nCommand should have thrown an exception"
80 } catch {
81     Assert-Equals -actual $_.Exception.Message -expected "invalid working directory path 'invalid path here'"
82 }
83 
84 $test_name = "invalid arguments"
85 $actual = Run-Command -command "ipconfig.exe /asdf"
86 Assert-Equals -actual $actual.rc -expected 1
87 
88 $test_name = "test stdout and stderr streams"
89 $actual = Run-Command -command "cmd.exe /c echo stdout && echo stderr 1>&2"
90 Assert-Equals -actual $actual.rc -expected 0
91 Assert-Equals -actual $actual.stdout -expected "stdout `r`n"
92 Assert-Equals -actual $actual.stderr -expected "stderr `r`n"
93 
94 $test_name = "Test UTF8 output from stdout stream"
95 $actual = Run-Command -command "powershell.exe -ExecutionPolicy ByPass -Command `"Write-Host '��'`""
96 Assert-Equals -actual $actual.rc -expected 0
97 Assert-Equals -actual $actual.stdout -expected "��`n"
98 Assert-Equals -actual $actual.stderr -expected ""
99 
100 $test_name = "test default environment variable"
101 Set-Item -Path env:TESTENV -Value "test"
102 $actual = Run-Command -command "cmd.exe /c set"
103 $env_present = $actual.stdout -split "`r`n" | Where-Object { $_ -eq "TESTENV=test" }
104 if ($null -eq $env_present) {
105     Fail-Json -obj $result -message "Test $test_name failed`nenvironment variable TESTENV not found in stdout`n$($actual.stdout)"
106 }
107 
108 $test_name = "test custom environment variable1"
109 $actual = Run-Command -command "cmd.exe /c set" -environment @{ TESTENV2 = "testing" }
110 $env_not_present = $actual.stdout -split "`r`n" | Where-Object { $_ -eq "TESTENV=test" }
111 $env_present = $actual.stdout -split "`r`n" | Where-Object { $_ -eq "TESTENV2=testing" }
112 if ($null -ne $env_not_present) {
113     Fail-Json -obj $result -message "Test $test_name failed`nenvironment variabel TESTENV found in stdout when it should be`n$($actual.stdout)"
114 }
115 if ($null -eq $env_present) {
116     Fail-json -obj $result -message "Test $test_name failed`nenvironment variable TESTENV2 not found in stdout`n$($actual.stdout)"
117 }
118 
119 $test_name = "input test"
120 $wrapper = @"
121 begin {
122     `$string = ""
123 } process {
124     `$current_input = [string]`$input
125     `$string += `$current_input
126 } end {
127     Write-Host `$string
128 }
129 "@
130 $encoded_wrapper = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($wrapper))
131 $actual = Run-Command -command "powershell.exe -ExecutionPolicy ByPass -EncodedCommand $encoded_wrapper" -stdin "Ansible"
132 Assert-Equals -actual $actual.stdout -expected "Ansible`n"
133 
134 $result.data = "success"
135 Exit-Json -obj $result
136