openssh-portable/contrib/win32/openssh/bash_script_iterator.ps1

277 lines
10 KiB
PowerShell

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)
[Parameter(Mandatory=$false)] [string[]] $TestFilePath,
[Parameter(Mandatory=$false)] [string] $ArtifactsPath=".",
[switch] $SkipCleanup,
[switch] $SkipInstallSSHD
)
# 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
$ArtifactsPath=resolve-path $ArtifactsPath -ErrorAction Stop | select -ExpandProperty Path
if ($TestFilePath) {
$TestFilePath=resolve-path $TestFilePath -ErrorAction Stop | select -ExpandProperty Path
# convert to bash format
$TestFilePath=$TestFilePath -replace "\\","/"
}
# Make sure config.h exists. It is used by 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
}
# store user directory
$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.
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 (!(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-Output "Failed to set HKLM:\Software\OpenSSH\DefaultShell to $ShellPath"
exit
}
# 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
}
$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/" # "/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/" # "/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
$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
}
# output to terminal
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 -ErrorAction Stop
# remove the summary, output files.
$test_summary="$ArtifactsPath\\bashtest_summary.txt"
$test_output="$ArtifactsPath\\bashtest_output.txt"
$null = Remove-Item -Force $test_summary -ErrorAction SilentlyContinue
$null = Remove-Item -Force $test_output -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.
# agent.sh, krl.sh - User Cert authentication fails
# key-options.sh - pty testcases are failing (bug in conpty. conpty fails to launch cygwin bash)
# integrity.sh - It's dependent on regress\modpipe.exe, test is complicated. Need to debug more
# authinfo.sh - spawned conpty inherits all the environment variables from sshd.
# forward-control.sh - Need to debug more.
[string]$known_failed_testcases = "agent.sh key-options.sh forward-control.sh integrity.sh krl.sh authinfo.sh"
[string]$known_failed_testcases_skipped = [string]::Empty
$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
}
foreach($test_case in $all_tests) {
if($TestFilePath) {
$TEST=$test_case
} else {
if(!$test_case.Contains(".sh")) {
$TEST=$BashTestsPath+"/"+$test_case+".sh"
} else {
$TEST=$BashTestsPath+"/"+$test_case
}
}
$test_case_name = [System.IO.Path]::GetFileName($TEST)
if($known_failed_testcases.Contains($test_case_name))
{
Write-Output "Skip the known failed test:$test_case_name"
$known_failed_testcases_skipped = $known_failed_testcases_skipped + "$test_case_name "
}
else
{
$msg="Executing $test_case_name " +[System.DateTime]::Now
Write-Output $msg
&$env:ShellPath -c "/usr/bin/sh $BashTestsPath/test-exec.sh $BashTestsPath/$temp_test_path $TEST" #>$null 2>&1
if($?)
{
$msg="$test_case_name PASSED " +[System.DateTime]::Now
Write-Output $msg
$total_tests_passed++
}
else
{
$msg="$test_case_name FAILED " +[System.DateTime]::Now
Write-Output $msg
$total_tests_failed++
$failed_testcases=$failed_testcases + "$test_case_name "
}
}
$total_tests++
}
$end_time = (Get-Date)
# Create artifacts
"Start time: $start_time" | Out-File -FilePath $test_summary -Append
"End time: $end_time" | Out-File -FilePath $test_summary -Append
"Total execution time: " + (NEW-TIMESPAN -Start $start_time -End $end_time).ToString("hh\:mm\:ss") | Out-File -FilePath $test_summary -Append
"Tests executed: $total_tests" | Out-File -FilePath $test_summary -Append
"Tests passed: $total_tests_passed" | Out-File -FilePath $test_summary -Append
"Tests failed: $total_tests_failed" | Out-File -FilePath $test_summary -Append
"Failed tests: $failed_testcases" | Out-File -FilePath $test_summary -Append
"Skipped known failed tests: $known_failed_testcases_skipped" | Out-File -FilePath $test_summary -Append
Write-Output "Artifacts are saved to $ArtifactsPath"
#output the summary
Write-Output "================================="
cat $test_summary
Write-Output "================================="
}
finally
{
# 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
}