forked from openssh/openssh-portable
-
Notifications
You must be signed in to change notification settings - Fork 334
/
Copy pathbash_tests_iterator.ps1
303 lines (265 loc) · 11.7 KB
/
bash_tests_iterator.ps1
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
param (
# Path to openssh binaries
[Parameter(Mandatory=$true)] [string] $OpenSSHBinPath,
# Path of regress folder which has all the bash testcases.
[Parameter(Mandatory=$true)] [string] $BashTestsPath,
# Path to CYGWIN / WSL.
[Parameter(Mandatory=$true)] [string] $ShellPath,
# Individual bash test file (Ex - connect.sh, scp.sh)
[Parameter(Mandatory=$false)] [string[]] $TestFilePath,
[Parameter(Mandatory=$false)] [string] $ArtifactsDirectoryPath=".",
[switch] $SkipCleanup,
[switch] $SkipInstallSSHD
)
$ErrorActionPreference = 'Continue'
# Resolve the relative paths
$OpenSSHBinPath = Resolve-Path $OpenSSHBinPath -ErrorAction Stop | select -ExpandProperty Path
$BashTestsPath = Resolve-Path $BashTestsPath -ErrorAction Stop | select -ExpandProperty Path
$ShellPath = Resolve-Path $ShellPath -ErrorAction Stop | select -ExpandProperty Path
$ArtifactsDirectoryPath = Resolve-Path $ArtifactsDirectoryPath -ErrorAction Stop | select -ExpandProperty Path
if ($TestFilePath) {
$TestFilePath = Resolve-Path $TestFilePath -ErrorAction Stop | select -ExpandProperty Path
# convert to bash format
$TestFilePath = $TestFilePath -replace "\\","/"
}
$OriginalSystemPath = [System.Environment]::GetEnvironmentVariable('Path', [System.EnvironmentVariableTarget]::Machine)
# Make sure config.h exists. It is used in some bashstests (Ex - sftp-glob.sh, cfgparse.sh)
# first check in $BashTestsPath folder. If not then it's parent folder. If not then in the $OpenSSHBinPath
if(Test-Path "$BashTestsPath\config.h" -PathType Leaf) {
$configPath = "$BashTestsPath\config.h"
} elseif(Test-Path "$BashTestsPath\..\config.h" -PathType Leaf) {
$configPath = Resolve-Path "$BashTestsPath\..\config.h" -ErrorAction Stop | select -ExpandProperty Path
} elseif(Test-Path "$OpenSSHBinPath\config.h" -PathType Leaf) {
$configPath = "$OpenSSHBinPath\config.h"
} else {
Write-Error "Couldn't find config.h"
exit
}
$user_pwd = pwd | select -ExpandProperty Path
# If we are using a SKU with desired OpenSSH binaries then we can skip these steps.
if(!$SkipInstallSSHD) {
# Make sure install-sshd.ps1 exists.
# This is required only for ssh-agent related bash tests.
if(!(Test-Path "$PSScriptRoot\install-sshd.ps1" -PathType Leaf)) {
Write-Error "$PSScriptRoot\install-sshd.ps1 doesn't exists"
exit
}
# Make sure uninstall-sshd.ps1 exists.
if(!(Test-Path "$PSScriptRoot\uninstall-sshd.ps1" -PathType Leaf)) {
Write-Error "$PSScriptRoot\uninstall-sshd.ps1 doesn't exists"
exit
}
#copy to binary folder and execute install-sshd.ps1
Copy-Item $PSScriptRoot\install-sshd.ps1 -Force $OpenSSHBinPath
Copy-Item $PSScriptRoot\uninstall-sshd.ps1 -Force $OpenSSHBinPath
# We need ssh-agent to be installed as service to run some bash tests.
& "$OpenSSHBinPath\install-sshd.ps1"
}
try
{
# set the default shell
$registryPath = "HKLM:\Software\OpenSSH"
$dfltShell = "DefaultShell"
# Fetch the user configured default shell.
$out = (Get-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue)
if ($out) {
$user_default_shell = $out.$dfltShell
Write-Output "User configured default shell: $user_default_shell"
}
if ($user_default_shell -ne $ShellPath)
{
if (!(Test-Path $registryPath)) {
# start and stop the sshd so that "HKLM:\Software\OpenSSH" registry path is created.
Start-Service sshd -ErrorAction Stop
Stop-Service sshd -ErrorAction SilentlyContinue
}
Set-ItemProperty -Path $registryPath -Name $dfltShell -Value $ShellPath -Force
$out = (Get-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue)
if ($out.$dfltShell -ne $ShellPath) {
Write-Error "Failed to set HKLM:\Software\OpenSSH\DefaultShell to $ShellPath"
exit
}
Write-Output "Successfully set the default shell (HKLM:\Software\OpenSSH\DefaultShell) to $ShellPath"
}
# Prepend shell path to PATH. This is required to make the shell commands (like sleep, cat, etc) work properly.
$env:TEST_SHELL_PATH = $ShellPath -replace "\\","/"
$TEST_SHELL_DIR = split-path $ShellPath
if(!$env:path.StartsWith($TEST_SHELL_DIR, "CurrentCultureIgnoreCase"))
{
$env:path = $TEST_SHELL_DIR + ";" + $env:path
}
# Prepend shell path to User PATH in the registry so that SSHD authenticated child process can inherit it.
# We can probably delete the logic above to add it to the process PATH, but there is no need.
[System.Environment]::SetEnvironmentVariable('Path', $TEST_SHELL_DIR + ";" + $OpenSSHBinPath + ";" + $OriginalSystemPath, [System.EnvironmentVariableTarget]::Machine)
# set SSH askpass
$TEST_SSH_ASKPASS = Join-Path $BashTestsPath "pesterTests\utilities\askpass_util\askpass_util.exe"
if (!(Test-Path $TEST_SSH_ASKPASS)) {
Write-Error "SSHAskpass:$TEST_SSH_ASKPASS doesn't exist"
exit
}
$BashTestsPath = $BashTestsPath -replace "\\","/"
Push-location $BashTestsPath
# BUILDDIR: config.h location.
# BUILDDIR is used by bashstests (Ex - sftp-glob.sh, cfgparse.sh)
$BUILDDIR = Resolve-Path(split-path $configpath) | select -ExpandProperty Path
$tmp = &$ShellPath -c pwd
if ($tmp.StartsWith("/cygdrive/")) {
$shell_drv_fmt = "/cygdrive/" # cygwin
$BUILDDIR = &$ShellPath -c "cygpath -u '$BUILDDIR'"
$OpenSSHBinPath_shell_fmt=&$ShellPath -c "cygpath -u '$OpenSSHBinPath'"
$BashTestsPath = &$ShellPath -c "cygpath -u '$BashTestsPath'"
} elseif ($tmp.StartsWith("/mnt/")) {
$shell_drv_fmt = "/mnt/" # WSL bash
$BUILDDIR = &$ShellPath -c "wslpath -u '$BUILDDIR'"
$OpenSSHBinPath_shell_fmt=&$ShellPath -c "wslpath -u '$OpenSSHBinPath'"
$BashTestsPath = &$ShellPath -c "wslpath -u '$BashTestsPath'"
}
#set the environment variables.
$env:ShellPath = $ShellPath
$env:SSH_TEST_ENVIRONMENT = 1
$env:TEST_SSH_TRACE = "yes"
$env:TEST_SHELL = "/bin/sh"
$env:TEST_SSH_PORT = 22
$env:TEST_SSH_SSH = $OpenSSHBinPath_shell_fmt+"/ssh.exe"
$env:TEST_SSH_SSHD = $OpenSSHBinPath_shell_fmt+"/sshd.exe"
$env:TEST_SSH_SSHAGENT = $OpenSSHBinPath_shell_fmt+"/ssh-agent.exe"
$env:TEST_SSH_SSHADD = $OpenSSHBinPath_shell_fmt+"/ssh-add.exe"
$env:TEST_SSH_SSHKEYGEN = $OpenSSHBinPath_shell_fmt+"/ssh-keygen.exe"
$env:TEST_SSH_SSHKEYSCAN = $OpenSSHBinPath_shell_fmt+"/ssh-keyscan.exe"
$env:TEST_SSH_SFTP = $OpenSSHBinPath_shell_fmt+"/sftp.exe"
$env:TEST_SSH_SFTPSERVER = $OpenSSHBinPath_shell_fmt+"/sftp-server.exe"
$env:TEST_SSH_SCP = $OpenSSHBinPath_shell_fmt+"/scp.exe"
$env:BUILDDIR = $BUILDDIR
$env:TEST_WINDOWS_SSH = 1
$env:TEST_SSH_ASKPASS = $TEST_SSH_ASKPASS
$user = &"$env:windir\system32\whoami.exe"
if($user.Contains($env:COMPUTERNAME.ToLower())) {
# for local accounts, skip COMPUTERNAME
$user = Split-Path $user -leaf
$env:TEST_SSH_USER = $user
} else {
# for domain user convert "domain\user" to "domain/user".
$user = $user -replace "\\","/"
$env:TEST_SSH_USER = $user
$env:TEST_SSH_USER_DOMAIN = Split-Path $user
}
Write-Output "USER: $env:TEST_SSH_USER"
Write-Output "DOMAIN: $env:TEST_SSH_USER_DOMAIN"
Write-Output "OpenSSHBinPath: $OpenSSHBinPath_shell_fmt"
Write-Output "BUILDDIR: $BUILDDIR"
Write-Output "BashTestsPath: $BashTestsPath"
# remove, create the temp test directory
$temp_test_path = "temp_test"
$null = Remove-Item -Recurse -Force $temp_test_path -ErrorAction SilentlyContinue
$null = New-Item -ItemType directory -Path $temp_test_path -Force -ErrorAction Stop
# remove the summary, output files.
$bash_test_summary = "$ArtifactsDirectoryPath\bash_tests_summary.txt"
$bash_test_log_file = "$ArtifactsDirectoryPath\bash_tests_output.log"
$null = Remove-Item -Force $bash_test_summary -ErrorAction SilentlyContinue
$null = Remove-Item -Force $bash_test_log_file -ErrorAction SilentlyContinue
[int]$total_tests = 0
[int]$total_tests_passed = 0
[int]$total_tests_failed = 0
[string]$failed_testcases = [string]::Empty
# These are the known failed testcases.
# transfer.sh, rekey.sh tests fail on CygWin v3.4.0, but succeeds with v3.3.6
$known_failed_testcases = @("agent.sh", "key-options.sh", "forward-control.sh", "integrity.sh", "krl.sh", "cert-hostkey.sh", "cert-userkey.sh", "percent.sh", "transfer.sh", "rekey.sh")
$known_failed_testcases_skipped = @()
$start_time = (Get-Date)
if($TestFilePath) {
# User can specify individual test file path.
$all_tests = $TestFilePath
} else {
# picking the gawk.exe from bash folder.
# TODO - check if gawk.exe is present in WSL.
$all_tests = gawk.exe 'sub(/.*LTESTS=/,""""){f=1} f{print $1; if (!/\\\\/) exit}' Makefile
}
Write-Output ""
foreach ($test_file in $all_tests) {
if ($TestFilePath) {
$TEST = $test_file
} else {
if (!$test_file.Contains(".sh")) {
$TEST = $BashTestsPath + "/" + $test_file + ".sh"
} else {
$TEST = $BashTestsPath + "/" + $test_file
}
}
$test_file_name = [System.IO.Path]::GetFileName($TEST)
if ($known_failed_testcases.Contains($test_file_name))
{
Write-Output "Skip the known failed test:$test_file_name [$($all_tests.IndexOf($test_file) + 1) of $($all_tests.count)]"
$known_failed_testcases_skipped += "$test_file_name"
}
else
{
$msg = "Run $test_file_name [$($all_tests.IndexOf($test_file) + 1) of $($all_tests.count)] " + [System.DateTime]::Now
Write-Output $msg | Tee-Object -FilePath $bash_test_log_file -Append -ErrorAction Stop
&$env:ShellPath -c "/usr/bin/sh $BashTestsPath/test-exec.sh $BashTestsPath/$temp_test_path $TEST 2>&1" | Out-File -FilePath $bash_test_log_file -Append -ErrorAction Stop
if ($?)
{
$msg = "$test_file_name PASSED " + [System.DateTime]::Now
Write-Output $msg | Tee-Object -FilePath $bash_test_log_file -Append -ErrorAction Stop
$total_tests_passed++
}
else
{
$msg = "$test_file_name FAILED " + [System.DateTime]::Now
Write-Output $msg | Tee-Object -FilePath $bash_test_log_file -Append -ErrorAction Stop
$total_tests_failed++
$failed_testcases = $failed_testcases + "$test_file_name "
}
}
$total_tests++
}
$end_time = (Get-Date)
# Create artifacts
$Global:bash_tests_summary = [ordered]@{
"StartTime" = $start_time.ToString();
"EndTime" = $end_time.ToString();
"TotalExecutionTime" = (NEW-TIMESPAN -Start $start_time -End $end_time).ToString("hh\:mm\:ss");
"TotalBashTests" = $total_tests;
"TotalBashTestsPassed" = $total_tests_passed;
"TotalBashTestsFailed" = $total_tests_failed;
"TotalBashTestsSkipped" = $known_failed_testcases_skipped.Count;
"FailedBashTests" = $failed_testcases;
"SkippedBashTests" = $known_failed_testcases_skipped -join ', ';
"BashTestSummaryFile" = $bash_test_summary
"BashTestLogFile" = $bash_test_log_file
}
$Global:bash_tests_summary | ConvertTo-Json | Out-File -FilePath $bash_test_summary
#output the summary
Write-Output "`n============================================"
Get-Content -Raw $bash_test_summary
Write-Output "============================================`n"
}
finally
{
# Restore User Path variable in the registry once the tests finish running.
[System.Environment]::SetEnvironmentVariable('Path', $OriginalSystemPath, [System.EnvironmentVariableTarget]::Machine)
# remove temp test directory
if (!$SkipCleanup)
{
# remove temp test folder
&$ShellPath -c "rm -rf $BashTestsPath/temp_test"
if(!$SkipInstallSSHD) {
# Uninstall the sshd, ssh-agent service
& "$PSScriptRoot\uninstall-sshd.ps1"
}
# Remove the test environment variable
Remove-Item ENV:\SSH_TEST_ENVIRONMENT
# Revert to user configured default shell.
if($user_default_shell) {
Set-ItemProperty -Path $registryPath -Name $dfltShell -Value $user_default_shell -Force
$out=(Get-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue)
if($out.$dfltShell -eq $user_default_shell) {
Write-Output "Reverted user configured default shell to $user_default_shell"
} else {
Write-Output "Failed to set HKLM:\Software\OpenSSH\DefaultShell to $user_default_shell"
}
} else {
Remove-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue
}
}
Push-location $user_pwd
}