From 21dfa768b7592d81fa863332db6060f48efedffc Mon Sep 17 00:00:00 2001 From: Tess Gauthier Date: Mon, 24 Jun 2024 17:21:05 -0400 Subject: [PATCH 01/13] add -T/-t pester tests --- regress/pesterTests/SCP.Tests.ps1 | 256 +++++++++++++++++++++-------- regress/pesterTests/SFTP.Tests.ps1 | 67 ++++++-- regress/pesterTests/SSH.Tests.ps1 | 60 ++++--- 3 files changed, 278 insertions(+), 105 deletions(-) diff --git a/regress/pesterTests/SCP.Tests.ps1 b/regress/pesterTests/SCP.Tests.ps1 index 1c3580c83804..698d4cc48fca 100644 --- a/regress/pesterTests/SCP.Tests.ps1 +++ b/regress/pesterTests/SCP.Tests.ps1 @@ -24,7 +24,7 @@ Describe "Tests for scp command" -Tags "CI" { $SourceFileWildCardFile1 = Join-Path $SourceDir $wildcardFileName1 $DestinationDir = Join-Path "$($OpenSSHTestInfo["TestDataPath"])\SCP" "DestDir" $DestinationDirWildcardPath = Join-Path "$($OpenSSHTestInfo["TestDataPath"])\SCP" "DestD?r" - $DestinationFilePath = Join-Path $DestinationDir $fileName1 + $DestinationFilePath = Join-Path $DestinationDir $fileName1 $NestedSourceDir= Join-Path $SourceDir "nested" $NestedSourceFilePath = Join-Path $NestedSourceDir $fileName2 $null = New-Item $SourceDir -ItemType directory -Force -ErrorAction SilentlyContinue @@ -35,7 +35,7 @@ Describe "Tests for scp command" -Tags "CI" { "Test content333" | Set-content -Path $SourceFilePath3 "Test content in nested dir" | Set-content -Path $NestedSourceFilePath $null = New-Item $DestinationDir -ItemType directory -Force -ErrorAction SilentlyContinue - $sshcmd = (get-command ssh).Path + $sshcmd = (get-command ssh).Path # for symlink tests $SourceDirSymLinkName = "SourceDirSymLink" @@ -50,6 +50,10 @@ Describe "Tests for scp command" -Tags "CI" { $SymLinkDir = Join-Path $SourceDirSymLink $SymLinkName $null = New-Item -Path $SymLinkDir -ItemType SymbolicLink -Value $tmpDir + # for large file transfer tests + $largeFileName = 'largefile.txt' + fsutil file createNew $largeFileName 1000000000 + $server = $OpenSSHTestInfo["Target"] $port = $OpenSSHTestInfo["Port"] $ssouser = $OpenSSHTestInfo["SSOUser"] @@ -57,7 +61,7 @@ Describe "Tests for scp command" -Tags "CI" { $testData = @( @{ Title = 'Simple copy local file to local file' - Source = $SourceFilePath + Source = $SourceFilePath Destination = $DestinationFilePath }, @{ @@ -71,14 +75,14 @@ Describe "Tests for scp command" -Tags "CI" { Source = "test_target:$SourceFilePath" Destination = $DestinationFilePath Options = "-p -c aes128-ctr -C" - }, + }, @{ Title = 'Simple copy local file to local dir' Source = $SourceFilePath Destination = $DestinationDir }, @{ - Title = 'simple copy local file to remote dir' + Title = 'simple copy local file to remote dir' Source = $SourceFilePath Destination = "test_target:$DestinationDir" Options = "-C -q" @@ -99,7 +103,7 @@ Describe "Tests for scp command" -Tags "CI" { Destination = $DestinationDir }, @{ - Title = 'simple copy local file to remote dir with wild card name' + Title = 'simple copy local file to remote dir with wild card name' Source = $SourceFilePath Destination = "test_target:$DestinationFilePath" Options = "-C -q" @@ -120,7 +124,7 @@ Describe "Tests for scp command" -Tags "CI" { Options = "-r " }, @{ - Title = 'copy from remote dir to local dir' + Title = 'copy from remote dir to local dir' Source = "test_target:$sourceDir" Destination = $DestinationDir Options = "-C -r -q" @@ -141,13 +145,27 @@ Describe "Tests for scp command" -Tags "CI" { Options = "-r " }, @{ - Title = 'symlink copy from remote dir to local dir' + Title = 'symlink copy from remote dir to local dir' Source = "test_target:$SourceDirSymLink" Destination = $DestinationDir Options = "-C -r -q" } ) + $testData3 = @( + @{ + Title = 'copy large file from local dir to remote dir' + Source = $sourceDir + Destination = "test_target:$DestinationDir" + Options = "-S `"$sshcmd`"" + }, + @{ + Title = 'copy large file from remote dir to local dir' + Source = "test_target:$sourceDir" + Destination = $DestinationDir + } + ) + # for the first time, delete the existing log files. if ($OpenSSHTestInfo['DebugMode']) { @@ -163,16 +181,32 @@ Describe "Tests for scp command" -Tags "CI" { { Copy-Item "$env:ProgramData\ssh\logs\ssh-agent.log" "$testDir\failedagent$tI.log" -Force -ErrorAction SilentlyContinue Copy-Item "$env:ProgramData\ssh\logs\sshd.log" "$testDir\failedsshd$tI.log" -Force -ErrorAction SilentlyContinue - + # clear the ssh-agent, sshd logs so that next testcase will get fresh logs. Clear-Content "$env:ProgramData\ssh\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue Clear-Content "$env:ProgramData\ssh\logs\sshd.log" -Force -ErrorAction SilentlyContinue } - + return $false } return $true } + + function ConfigureDefaultShell { + param + ( + [string] $default_shell_path, + [string] $default_shell_cmd_option_val = $null + ) + + if (!(Test-Path $dfltShellRegPath)) { + New-Item -Path $dfltShellRegPath -Force | Out-Null + } + New-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -Value $default_shell_path -PropertyType String -Force + if ($default_shell_cmd_option_val -ne $null) { + New-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -Value $default_shell_cmd_option_val -PropertyType String -Force + } + } } AfterAll { @@ -205,74 +239,160 @@ Describe "Tests for scp command" -Tags "CI" { Get-ChildItem $DestinationDir -Recurse | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Start-Sleep 1 $tI++ - } - - - It 'File copy: ' -TestCases:$testData { - param([string]$Title, $Source, $Destination, [string]$Options) - iex "scp $Options $Source $Destination" - $LASTEXITCODE | Should Be 0 - #validate file content. DestPath is the path to the file. - CheckTarget -target $DestinationFilePath | Should Be $true - - $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 - $equal | Should Be $true - - if($Options.contains("-p ") -and [environment]::OSVersion.Version.Major -ge 10) - { - $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0 + } + + Context "$tI - Basic Scenarios" { + + It 'File copy: <Title> ' -TestCases:$testData { + param([string]$Title, $Source, $Destination, [string]$Options) + iex "scp $Options $Source $Destination" + $LASTEXITCODE | Should Be 0 + #validate file content. DestPath is the path to the file. + CheckTarget -target $DestinationFilePath | Should Be $true + + $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 $equal | Should Be $true + + if($Options.contains("-p ") -and [environment]::OSVersion.Version.Major -ge 10) + { + $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0 + $equal | Should Be $true + } } - } - - It 'Directory recursive copy: <Title> ' -TestCases:$testData1 { - param([string]$Title, $Source, $Destination, [string]$Options) - - iex "scp $Options $Source $Destination" - $LASTEXITCODE | Should Be 0 - CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true - - $equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0 - $equal | Should Be $true - - if($Options.contains("-p ")) - { - $equal = @(Compare-Object (Get-Item -path $SourceDir).LastWriteTime.DateTime (Get-Item -path (join-path $DestinationDir $SourceDirName)).LastWriteTime.DateTime).Length -eq 0 + + It 'Directory recursive copy: <Title> ' -TestCases:$testData1 { + param([string]$Title, $Source, $Destination, [string]$Options) + + iex "scp $Options $Source $Destination" + $LASTEXITCODE | Should Be 0 + CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true + + $equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0 $equal | Should Be $true + + if($Options.contains("-p ")) + { + $equal = @(Compare-Object (Get-Item -path $SourceDir).LastWriteTime.DateTime (Get-Item -path (join-path $DestinationDir $SourceDirName)).LastWriteTime.DateTime).Length -eq 0 + $equal | Should Be $true + } + + $equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0 + $equal | Should Be $true + + if($Options.contains("-p ") -and $IsWindows -and ($PSVersionTable.PSVersion.Major -gt 2)) + { + $equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir).LastWriteTime.DateTime (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ).LastWriteTime.DateTime).Length -eq 0 + $equal | Should Be $true + } } - $equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0 - $equal | Should Be $true + It 'Directory with symlink recursive copy: <Title> ' -TestCases:$testData2 { + param([string]$Title, $Source, $Destination, [string]$Options) - if($Options.contains("-p ") -and $IsWindows -and ($PSVersionTable.PSVersion.Major -gt 2)) - { - $equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir).LastWriteTime.DateTime (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ).LastWriteTime.DateTime).Length -eq 0 + iex "scp $Options $Source $Destination" + $LASTEXITCODE | Should Be 0 + $expectedFilepath = join-path $DestinationDir $SourceDirSymLinkName $SymLinkName $fileName1 + CheckTarget -target $expectedFilepath | Should Be $true + Get-Content $expectedFilepath | Should Be "Test content in tmp dir for sym link" + } + + It 'File copy: path contains wildcards ' { + $Source = Join-Path $SourceDir $wildcardFileName2 + scp -p $Source $DestinationDir + $LASTEXITCODE | Should Be 0 + #validate file content. DestPath is the path to the file. + CheckTarget -target $DestinationFilePath | Should Be $true + CheckTarget -target (Join-path $DestinationDir $fileName3) | Should Be $true + + $equal = @(Compare-Object (Get-ChildItem -path $Source) (Get-ChildItem -path (join-path $DestinationDir $wildcardFileName2)) -Property Name, Length ).Length -eq 0 + $equal | Should Be $true + + $equal = @(Compare-Object (Get-ChildItem -path $Source).LastWriteTime.DateTime (Get-ChildItem -path (join-path $DestinationDir $wildcardFileName3)).LastWriteTime.DateTime ).Length -eq 0 + $equal | Should Be $true + } + + It '<Title> ' -TestCases:$testData3 { + param([string]$Title, $Source, $Destination, [string]$Options) + + iex "scp $Options $Source $Destination" + $LASTEXITCODE | Should Be 0 + + $DestinationFilePath = Join-Path $Destination $largeFileName + CheckTarget -target $DestinationFilePath | Should Be $true + + $equal = @(Compare-Object (Get-ChildItem -path $Source) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 + $equal | Should Be $true + + $equal = @(Compare-Object (Get-ChildItem -path $Source).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0 $equal | Should Be $true } } - It 'Directory with symlink recursive copy: <Title> ' -TestCases:$testData2 { - param([string]$Title, $Source, $Destination, [string]$Options) - - iex "scp $Options $Source $Destination" - $LASTEXITCODE | Should Be 0 - $expectedFilepath = join-path $DestinationDir $SourceDirSymLinkName $SymLinkName $fileName1 - CheckTarget -target $expectedFilepath | Should Be $true - Get-Content $expectedFilepath | Should Be "Test content in tmp dir for sym link" + Context "$tI - configure powershell default shell scenarios" { + BeforeAll { + $dfltShellRegPath = "HKLM:\Software\OpenSSH" + $dfltShellRegKeyName = "DefaultShell" + $dfltShellCmdOptionRegKeyName = "DefaultShellCommandOption" + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + $shell_path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).path + if($shell_path -ne $null) { + ConfigureDefaultShell -default_shell_path $shell_path -default_shell_cmd_option_val "-c" + } + } + AfterAll{ + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + } + + It 'File copy: <Title> ' -TestCases:$testData { + param([string]$Title, $Source, $Destination, [string]$Options) + iex "scp $Options $Source $Destination" + $LASTEXITCODE | Should Be 0 + #validate file content. DestPath is the path to the file. + CheckTarget -target $DestinationFilePath | Should Be $true + + $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 + $equal | Should Be $true + + if($Options.contains("-p ") -and [environment]::OSVersion.Version.Major -ge 10) + { + $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0 + $equal | Should Be $true + } + } } - It 'File copy: path contains wildcards ' { - $Source = Join-Path $SourceDir $wildcardFileName2 - scp -p $Source $DestinationDir - $LASTEXITCODE | Should Be 0 - #validate file content. DestPath is the path to the file. - CheckTarget -target $DestinationFilePath | Should Be $true - CheckTarget -target (Join-path $DestinationDir $fileName3) | Should Be $true - - $equal = @(Compare-Object (Get-ChildItem -path $Source) (Get-ChildItem -path (join-path $DestinationDir $wildcardFileName2)) -Property Name, Length ).Length -eq 0 - $equal | Should Be $true - - $equal = @(Compare-Object (Get-ChildItem -path $Source).LastWriteTime.DateTime (Get-ChildItem -path (join-path $DestinationDir $wildcardFileName3)).LastWriteTime.DateTime ).Length -eq 0 - $equal | Should Be $true + Context "$tI - configure shell-host default shell scenarios" { + BeforeAll { + $dfltShellRegPath = "HKLM:\Software\OpenSSH" + $dfltShellRegKeyName = "DefaultShell" + $dfltShellCmdOptionRegKeyName = "DefaultShellCommandOption" + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + $shell_path = (Get-Command ssh-shellhost -ErrorAction SilentlyContinue).path + ConfigureDefaultShell -default_shell_path $shell_path + } + AfterAll{ + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + } + + It 'File copy: <Title> ' -TestCases:$testData { + param([string]$Title, $Source, $Destination, [string]$Options) + iex "scp $Options $Source $Destination" + $LASTEXITCODE | Should Be 0 + #validate file content. DestPath is the path to the file. + CheckTarget -target $DestinationFilePath | Should Be $true + + $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 + $equal | Should Be $true + + if($Options.contains("-p ") -and [environment]::OSVersion.Version.Major -ge 10) + { + $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0 + $equal | Should Be $true + } + } } -} +} diff --git a/regress/pesterTests/SFTP.Tests.ps1 b/regress/pesterTests/SFTP.Tests.ps1 index a0a35f380a76..d45ad69f2afd 100644 --- a/regress/pesterTests/SFTP.Tests.ps1 +++ b/regress/pesterTests/SFTP.Tests.ps1 @@ -11,7 +11,7 @@ Describe "SFTP Test Cases" -Tags "CI" { } $rootDirectory = "$($OpenSSHTestInfo["TestDataPath"])\SFTP" - + $outputFileName = "output.txt" $batchFileName = "sftp-batchcmds.txt" $tempFileName = "tempFile.txt" @@ -20,6 +20,10 @@ Describe "SFTP Test Cases" -Tags "CI" { $tempUnicodeFileName = "tempFile_язык.txt" $tempUnicodeFilePath = Join-Path $rootDirectory $tempUnicodeFileName + $largeFileName = "largeFile.txt" + $largeFilePath = Join-Path $rootDirectory $largeFileName + fsutil file createNew $filename 1000000000 + $clientDirectory = Join-Path $rootDirectory 'client_dir' $serverDirectory = Join-Path $rootDirectory 'server_dir' @@ -32,10 +36,10 @@ Describe "SFTP Test Cases" -Tags "CI" { $port = $OpenSSHTestInfo["Port"] $ssouser = $OpenSSHTestInfo["SSOUser"] - Remove-item (Join-Path $rootDirectory "*.$outputFileName") -Force -ErrorAction SilentlyContinue + Remove-item (Join-Path $rootDirectory "*.$outputFileName") -Force -ErrorAction SilentlyContinue Remove-item (Join-Path $rootDirectory "*.$batchFileName") -Force -ErrorAction SilentlyContinue Remove-item (Join-Path $rootDirectory "*.log") -Force -ErrorAction SilentlyContinue - + $skip = $IsWindows -and ($PSVersionTable.PSVersion.Major -le 2) $testData1 = @( @@ -90,7 +94,7 @@ Describe "SFTP Test Cases" -Tags "CI" { options = '' commands = "put $tempUnicodeFilePath $serverDirectory ls $serverDirectory" - expectedoutput = (join-path $serverdirectory $tempUnicodeFileName) + expectedoutput = (join-path $serverdirectory $tempUnicodeFileName) }, @{ title = "get, ls for unicode file names" @@ -133,12 +137,12 @@ Describe "SFTP Test Cases" -Tags "CI" { ExpectedOutput = (Join-Path $clientDirectory "client_test_dir_язык") } ) - + $testData2 = @( @{ title = "rm, rmdir, rename for unicode file, directory" options = '-b $batchFilePath' - + tmpFileName1 = $tempUnicodeFileName tmpFilePath1 = $tempUnicodeFilePath tmpFileName2 = "tempfile_язык_2.txt" @@ -152,7 +156,7 @@ Describe "SFTP Test Cases" -Tags "CI" { @{ title = "rm, rmdir, rename for non-unicode file, directory" options = '-b $batchFilePath' - + tmpFileName1 = $tempFileName tmpFilePath1 = $tempFilePath tmpFileName2 = "tempfile_2.txt" @@ -165,6 +169,33 @@ Describe "SFTP Test Cases" -Tags "CI" { } ) + $testData3 = @( + @{ + title = "put, ls for large file transfer" + commands = "put $largeFilePath $serverDirectory + ls $serverDirectory" + expectedoutput = (join-path $serverdirectory $largeFileName) + }, + @{ + title = "get, ls for large file transfer" + commands = "get $largeFilePath $clientDirectory + ls $clientDirectory" + expectedoutput = (join-path $clientDirectory $largeFileName) + }, + @{ + title = "mput, ls for large file transfer" + commands = "mput $largeFilePath $serverDirectory + ls $serverDirectory" + expectedoutput = (join-path $serverdirectory $largeFileName) + }, + @{ + title = "mget, ls for large file transfer" + commands = "mget $largeFilePath $clientDirectory + ls $clientDirectory" + expectedoutput = (join-path $clientDirectory $largeFileName) + } + ) + # for the first time, delete the existing log files. if ($OpenSSHTestInfo['DebugMode']) { @@ -179,7 +210,7 @@ Describe "SFTP Test Cases" -Tags "CI" { Copy-Item "$env:ProgramData\ssh\logs\ssh-agent.log" "$rootDirectory\ssh-agent_$tI.log" -Force -ErrorAction SilentlyContinue Copy-Item "$env:ProgramData\ssh\logs\sshd.log" "$rootDirectory\sshd_$tI.log" -Force -ErrorAction SilentlyContinue Copy-Item "$env:ProgramData\ssh\logs\sftp-server.log" "$rootDirectory\sftp-server_$tI.log" -Force -ErrorAction SilentlyContinue - + # clear the ssh-agent, sshd logs so that next testcase will get fresh logs. Clear-Content "$env:ProgramData\ssh\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue Clear-Content "$env:ProgramData\ssh\logs\sshd.log" -Force -ErrorAction SilentlyContinue @@ -203,7 +234,7 @@ Describe "SFTP Test Cases" -Tags "CI" { AfterEach { CopyDebugLogs $tI++ - } + } It '<Title>' -TestCases:$testData1 { param([string]$Title, $Options, $Commands, $ExpectedOutput) @@ -270,9 +301,9 @@ Describe "SFTP Test Cases" -Tags "CI" { } It "$script:testId-ls lists items the user has no read permission" { - $adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid) + $adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid) $currentUserSid = Get-UserSID -User "$($env:USERDOMAIN)\$($env:USERNAME)" - + $permTestHasAccessFile = "permTestHasAccessFile.txt" $permTestHasAccessFilePath = Join-Path $serverDirectory $permTestHasAccessFile Remove-Item $permTestHasAccessFilePath -Force -ErrorAction SilentlyContinue @@ -289,7 +320,7 @@ Describe "SFTP Test Cases" -Tags "CI" { $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -b $batchFilePath test_target > $outputFilePath") iex $str $content = Get-Content $outputFilePath - + #cleanup $HasAccessPattern = $permTestHasAccessFilePath.Replace("\", "[/\\]") $matches = @($content | select-string -Pattern "^/$HasAccessPattern\s{0,}$") @@ -299,4 +330,16 @@ Describe "SFTP Test Cases" -Tags "CI" { $matches = @($content | select-string -Pattern "^/$NoAccessPattern\s{0,}$") $matches.count | Should be 1 } + + It '<Title>' -TestCases:$testData3 { + param([string]$Title, $Options, $Commands, $ExpectedOutput) + + Set-Content $batchFilePath -Encoding UTF8 -value $Commands + $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) -b $batchFilePath test_target > $outputFilePath") + iex $str + + #validate file content. + Test-Path $ExpectedOutput | Should be $true + $LASTEXITCODE | Should Be 0 + } } diff --git a/regress/pesterTests/SSH.Tests.ps1 b/regress/pesterTests/SSH.Tests.ps1 index 015727134e4b..d88dc7b105fe 100644 --- a/regress/pesterTests/SSH.Tests.ps1 +++ b/regress/pesterTests/SSH.Tests.ps1 @@ -5,9 +5,9 @@ Import-Module $PSScriptRoot\CommonUtils.psm1 -Force $tC = 1 $tI = 0 $suite = "sshclient" - + Describe "E2E scenarios for ssh client" -Tags "CI" { - BeforeAll { + BeforeAll { if($OpenSSHTestInfo -eq $null) { Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments." @@ -32,7 +32,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { <#$testData = @( @{ - Title = 'Simple logon no option'; + Title = 'Simple logon no option'; LogonStr = "$($server.localAdminUserName)@$($server.MachineName)" Options = "" }, @@ -42,7 +42,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { Options = "-C -l $($server.localAdminUserName)" } ) - + $testData1 = @( @{ Title = "logon using -i -q option" @@ -84,7 +84,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { [string] $default_shell_path, [string] $default_shell_cmd_option_val = $null ) - + if (!(Test-Path $dfltShellRegPath)) { New-Item -Path $dfltShellRegPath -Force | Out-Null } @@ -99,12 +99,12 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { $stderrFile=Join-Path $testDir "$tC.$tI.stderr.txt" $stdoutFile=Join-Path $testDir "$tC.$tI.stdout.txt" $logFile = Join-Path $testDir "$tC.$tI.log.txt" - } + } AfterEach {$tI++;} Context "$tC - Basic Scenarios" { - + BeforeAll {$tI=1} AfterAll{$tC++} @@ -117,13 +117,13 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { iex "cmd /c `"ssh -? 2> $stderrFile`"" $stderrFile | Should Contain "usage: ssh" } - + It "$tC.$tI - remote echo command" { iex "$sshDefaultCmd echo 1234" | Should Be "1234" } } - + Context "$tC - exit code (exit-status.sh)" { BeforeAll {$tI=1} AfterAll{$tC++} @@ -132,12 +132,12 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { foreach ($i in (0,1,4,5,44)) { ssh -p $port $ssouser@$server exit $i $LASTEXITCODE | Should Be $i - } + } } } Context "$tC - Redirection Scenarios" { - + BeforeAll {$tI=1} AfterAll{$tC++} @@ -192,7 +192,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { } } - + Context "$tC - configure powershell default shell Scenarios" { BeforeAll { $tI=1 @@ -205,13 +205,13 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { $tC++ Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue - } + } It "$tC.$tI - basic powershell" -skip:$skip { $o = ssh test_target Write-Output 1234 $o | Should Be "1234" } - + It "$tC.$tI - basic in powershell cmdlet" -skip:$skip { $o = ssh test_target "cd `$env:ProgramFiles;pwd" $LASTEXITCODE | Should Be 0 @@ -240,7 +240,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { It "$tC.$tI - single quotes in powershell cmdlet" -skip:$skip { # actual command line ssh target echo '$env:computername' $o = ssh test_target "echo '`$env:computername'" - $LASTEXITCODE | Should Be 0 + $LASTEXITCODE | Should Be 0 $o | Should Be `$env:computername } } @@ -257,9 +257,9 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue } - It "$tC.$tI - default shell as cmd" -skip:$skip { + It "$tC.$tI - default shell as cmd" -skip:$skip { $o = ssh test_target where cmd - $o | Should Contain "cmd" + $o | Should Contain "cmd" } It "$tC.$tI - cmd as default shell and double quotes in cmdline" { # actual command line ssh target echo "hello" @@ -269,7 +269,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { It "$tC.$tI - single quotes in powershell cmdlet" -skip:$skip { # actual command line ssh target echo '$env:computername' $o = ssh test_target "echo 'hello'" - $LASTEXITCODE | Should Be 0 + $LASTEXITCODE | Should Be 0 $o | Should Be "'hello'" } } @@ -290,15 +290,15 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { $o | Should Be "`"hello`"" } } - - Context "$tC - cmdline parameters" { + + Context "$tC - cmdline parameters" { BeforeAll {$tI=1} AfterAll{$tC++} It "$tC.$tI - verbose to file (-v -E)" { $o = ssh -v -E $logFile test_target echo 1234 $o | Should Be "1234" - #TODO - checks below are very inefficient (time taking). + #TODO - checks below are very inefficient (time taking). $logFile | Should Contain "OpenSSH_" $logFile | Should Contain "Exit Status 0" } @@ -333,11 +333,11 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { " Port $port" | Add-Content $goodConfigFile " User $ssouser" | Add-Content $goodConfigFile $o = ssh -F $goodConfigFile myhost echo 1234 - $o | Should Be "1234" + $o | Should Be "1234" } It "$tC.$tI - IP options - (-4) (-6)" { - # TODO - this test assumes target is localhost. + # TODO - this test assumes target is localhost. # make it work independent of target #-4 $o = ssh -4 -v -E $logFile test_target echo 1234 @@ -346,11 +346,11 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { #-4 $o = ssh -6 -v -E $logFile test_target echo 1234 $o | Should Be "1234" - $logFile | Should Contain "[::1]" + $logFile | Should Contain "[::1]" } It "$tC.$tI - auto populate known hosts" { - + $kh = Join-Path $testDir "$tC.$tI.known_hosts" $nul | Set-Content $kh # doing via cmd to intercept and drain stderr output @@ -367,5 +367,15 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { iex "cmd /c `"ssh -o ProxyCommand=`"`"$($env:ComSpec) /c echo test string for invalid proxy 1>&2`"`" abc 2>$stderrFile`"" $stderrFile | Should Contain "test string for invalid proxy" } + + It "$tC.$tI - force pseudo-terminal allocation (-t)" { + $o = ssh -t test_target echo 1234 + $o | Should Be "1234" + } + + It "$tC.$tI - disable pseudo-terminal allocation (-T)" { + $o = ssh -T test_target echo 1234 + $o | Should Be "1234" + } } } From 4ac536f489de4cd788f521196c1b3556e6831aec Mon Sep 17 00:00:00 2001 From: Tess Gauthier <tessgauthier@microsoft.com> Date: Thu, 17 Apr 2025 16:00:37 -0400 Subject: [PATCH 02/13] configure default shell for scp and sftp --- .../AzDOBuildTools/AzDOBuildTools.psm1 | 80 ++-- regress/pesterTests/SCP.Tests.ps1 | 121 +++-- regress/pesterTests/SFTP.Tests.ps1 | 452 ++++++++++-------- 3 files changed, 358 insertions(+), 295 deletions(-) diff --git a/contrib/win32/openssh/AzDOBuildTools/AzDOBuildTools.psm1 b/contrib/win32/openssh/AzDOBuildTools/AzDOBuildTools.psm1 index e4f3eec1ec56..742191ea6bb1 100644 --- a/contrib/win32/openssh/AzDOBuildTools/AzDOBuildTools.psm1 +++ b/contrib/win32/openssh/AzDOBuildTools/AzDOBuildTools.psm1 @@ -47,7 +47,7 @@ function Invoke-AzDOBuild function Install-OpenSSH { [CmdletBinding()] - param ( + param ( [Parameter(Mandatory=$true)] [string]$SourceDir, @@ -62,7 +62,7 @@ function Install-OpenSSH Copy-Item -Path "$SourceDir/*" -Destination $OpenSSHDir -Recurse -Force -Verbose - Push-Location $OpenSSHDir + Push-Location $OpenSSHDir try { @@ -81,8 +81,8 @@ function Install-OpenSSH { [Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE') } - - Start-Service -Name sshd + + Start-Service -Name sshd Start-Service -Name ssh-agent } finally @@ -100,7 +100,7 @@ function Install-OpenSSH function UnInstall-OpenSSH { [CmdletBinding()] - param ( + param ( [string]$OpenSSHDir = "$env:SystemDrive\OpenSSH" ) @@ -117,15 +117,15 @@ function UnInstall-OpenSSH Stop-Service ssh-agent -Force } & "$OpenSSHDir\uninstall-sshd.ps1" - + $machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE') $newMachineEnvironmentPath = $machinePath if ($machinePath.ToLower().Contains($OpenSSHDir.ToLower())) - { + { $newMachineEnvironmentPath = $newMachineEnvironmentPath.Replace("$OpenSSHDir;", '') $env:Path = $env:Path.Replace("$OpenSSHDir;", '') } - + if ($newMachineEnvironmentPath -ne $machinePath) { [Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE') @@ -136,7 +136,7 @@ function UnInstall-OpenSSH Pop-Location } - Remove-Item -Path $OpenSSHDir -Recurse -Force -ErrorAction SilentlyContinue + Remove-Item -Path $OpenSSHDir -Recurse -Force -ErrorAction SilentlyContinue } # @@ -181,7 +181,7 @@ function Invoke-OpenSSHTests } $xml = [xml](Get-Content $OpenSSHTestInfo["SetupTestResultsFile"] | out-string) - if ([int]$xml.'test-results'.failures -gt 0) + if ([int]$xml.'test-results'.failures -gt 0) { $errorMessage = "$($xml.'test-results'.failures) Setup Tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["SetupTestResultsFile"])." Write-BuildMessage -Message $errorMessage -Category Error @@ -218,31 +218,9 @@ function Invoke-OpenSSHTests # Run all E2E tests. Write-Verbose -Verbose -Message "Running E2E Tests..." Set-OpenSSHTestEnvironment -Confirm:$false - Invoke-OpenSSHE2ETest - if (($OpenSSHTestInfo -eq $null) -or (-not (Test-Path $OpenSSHTestInfo["E2ETestResultsFile"]))) - { - Write-BuildMessage -Message "Test result file $OpenSSHTestInfo["E2ETestResultsFile"] not found after tests." -Category Error - $AllTestsPassed = $false - } - else - { - $xml = [xml](Get-Content $OpenSSHTestInfo["E2ETestResultsFile"] | out-string) - if ([int]$xml.'test-results'.failures -gt 0) - { - $errorMessage = "$($xml.'test-results'.failures) E2E tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["E2ETestResultsFile"])." - Write-BuildMessage -Message $errorMessage -Category Error - $AllTestsPassed = $false - } - else - { - Write-BuildMessage -Message "All E2E tests passed!" -Category Information - } - } - - # Bash tests. - Write-Verbose -Verbose -Message "Running Bash Tests..." # Ensure CygWin is installed, and install from Chocolatey if needed. + # used for bash tests and default shell pester tests $cygwinInstalled = $true $cygwinInstallLocation = "$env:SystemDrive/cygwin" if (! (Test-Path -Path "$cygwinInstallLocation/bin/sh.exe")) @@ -269,9 +247,33 @@ function Invoke-OpenSSHTests } } - # Run UNIX bash tests. if ($cygwinInstalled) { + Invoke-OpenSSHE2ETest + if (($OpenSSHTestInfo -eq $null) -or (-not (Test-Path $OpenSSHTestInfo["E2ETestResultsFile"]))) + { + Write-BuildMessage -Message "Test result file $OpenSSHTestInfo["E2ETestResultsFile"] not found after tests." -Category Error + $AllTestsPassed = $false + } + else + { + $xml = [xml](Get-Content $OpenSSHTestInfo["E2ETestResultsFile"] | out-string) + if ([int]$xml.'test-results'.failures -gt 0) + { + $errorMessage = "$($xml.'test-results'.failures) E2E tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["E2ETestResultsFile"])." + Write-BuildMessage -Message $errorMessage -Category Error + $AllTestsPassed = $false + } + else + { + Write-BuildMessage -Message "All E2E tests passed!" -Category Information + } + } + + # Bash tests. + Write-Verbose -Verbose -Message "Running Bash Tests..." + + # Run UNIX bash tests. Write-Verbose -Verbose -Message "Starting Bash Tests..." Invoke-OpenSSHBashTests if (-not $Global:bash_tests_summary) @@ -306,7 +308,7 @@ function Invoke-OpenSSHTests else { $xml = [xml](Get-Content $OpenSSHTestInfo["UninstallTestResultsFile"] | out-string) - if ([int]$xml.'test-results'.failures -gt 0) + if ([int]$xml.'test-results'.failures -gt 0) { $errorMessage = "$($xml.'test-results'.failures) uninstall tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["UninstallTestResultsFile"])." Write-BuildMessage -Message $errorMessage -Category Error @@ -318,7 +320,7 @@ function Invoke-OpenSSHTests $OpenSSHTestInfo | Export-Clixml -Path "$repoRoot/OpenSSHTestInfo.xml" -Depth 10 # Writing out warning when the $Error.Count is non-zero. Tests Should clean $Error after success. - if ($Error.Count -gt 0) + if ($Error.Count -gt 0) { Write-BuildMessage -Message "Tests Should always clean $Error variable after success." -Category Warning } @@ -339,7 +341,7 @@ function Invoke-OpenSSHTests Collect OpenSSH pester test results into one directory #> function Copy-OpenSSHTestResults -{ +{ param ( [Parameter(Mandatory=$true)] [string] $ResultsPath @@ -352,7 +354,7 @@ function Copy-OpenSSHTestResults Write-Verbose -Verbose "Creating test results directory for artifacts upload: $ResultsPath" $null = New-Item -Path $ResultsPath -ItemType Directory -Force - + if (! (Test-Path -Path $ResultsPath)) { Write-BuildMessage -Message "Unable to write to test results path for test artifacts upload: $ResultsPath" -Category Error @@ -498,7 +500,7 @@ function Copy-UnitTests function Install-UnitTests { [CmdletBinding()] - param ( + param ( [Parameter(Mandatory=$true)] [string]$SourceDir, diff --git a/regress/pesterTests/SCP.Tests.ps1 b/regress/pesterTests/SCP.Tests.ps1 index 698d4cc48fca..81561b1d2dd5 100644 --- a/regress/pesterTests/SCP.Tests.ps1 +++ b/regress/pesterTests/SCP.Tests.ps1 @@ -52,7 +52,8 @@ Describe "Tests for scp command" -Tags "CI" { # for large file transfer tests $largeFileName = 'largefile.txt' - fsutil file createNew $largeFileName 1000000000 + $largeFilePath = Join-Path $sourceDir $largeFileName + fsutil file createNew $largeFilePath 1000000000 $server = $OpenSSHTestInfo["Target"] $port = $OpenSSHTestInfo["Port"] @@ -155,13 +156,13 @@ Describe "Tests for scp command" -Tags "CI" { $testData3 = @( @{ Title = 'copy large file from local dir to remote dir' - Source = $sourceDir + Source = $largeFilePath Destination = "test_target:$DestinationDir" Options = "-S `"$sshcmd`"" }, @{ Title = 'copy large file from remote dir to local dir' - Source = "test_target:$sourceDir" + Source = "test_target:$largeFilePath" Destination = $DestinationDir } ) @@ -328,70 +329,68 @@ Describe "Tests for scp command" -Tags "CI" { } } - Context "$tI - configure powershell default shell scenarios" { + Context "Configure various default shell scenarios" { BeforeAll { - $dfltShellRegPath = "HKLM:\Software\OpenSSH" - $dfltShellRegKeyName = "DefaultShell" - $dfltShellCmdOptionRegKeyName = "DefaultShellCommandOption" - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue - $shell_path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).path - if($shell_path -ne $null) { - ConfigureDefaultShell -default_shell_path $shell_path -default_shell_cmd_option_val "-c" - } + $dfltShellRegPath = "HKLM:\Software\OpenSSH" + $dfltShellRegKeyName = "DefaultShell" + $dfltShellCmdOptionRegKeyName = "DefaultShellCommandOption" + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue } - AfterAll{ - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue - } - - It 'File copy: <Title> ' -TestCases:$testData { - param([string]$Title, $Source, $Destination, [string]$Options) - iex "scp $Options $Source $Destination" - $LASTEXITCODE | Should Be 0 - #validate file content. DestPath is the path to the file. - CheckTarget -target $DestinationFilePath | Should Be $true - $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 - $equal | Should Be $true - - if($Options.contains("-p ") -and [environment]::OSVersion.Version.Major -ge 10) - { - $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0 - $equal | Should Be $true - } + AfterAll { + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue } - } - Context "$tI - configure shell-host default shell scenarios" { - BeforeAll { - $dfltShellRegPath = "HKLM:\Software\OpenSSH" - $dfltShellRegKeyName = "DefaultShell" - $dfltShellCmdOptionRegKeyName = "DefaultShellCommandOption" - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue - $shell_path = (Get-Command ssh-shellhost -ErrorAction SilentlyContinue).path - ConfigureDefaultShell -default_shell_path $shell_path - } - AfterAll{ - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue - } - - It 'File copy: <Title> ' -TestCases:$testData { - param([string]$Title, $Source, $Destination, [string]$Options) - iex "scp $Options $Source $Destination" - $LASTEXITCODE | Should Be 0 - #validate file content. DestPath is the path to the file. - CheckTarget -target $DestinationFilePath | Should Be $true - - $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 - $equal | Should Be $true + $shells = @( + @{ + Name = "Windows PowerShell" + Path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).Path + CmdOption = "/c" + }, + @{ + Name = "PowerShell Core" + Path = (Get-Command pwsh -ErrorAction SilentlyContinue).Path + CmdOption = $null + }, + @{ + Name = "Bash" + Path = (Get-Command bash -ErrorAction SilentlyContinue).Path + CmdOption = $null + }, + @{ + Name = "Cygwin" + Path = (Get-Command sh -ErrorAction SilentlyContinue).Path + CmdOption = $null + } + ) - if($Options.contains("-p ") -and [environment]::OSVersion.Version.Major -ge 10) - { - $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0 - $equal | Should Be $true + foreach ($shell in $shells) { + if ($shell.Path -ne $null) { + Context "Configure default shell as $($shell.Name)" { + BeforeAll { + ConfigureDefaultShell -default_shell_path $shell.Path -default_shell_cmd_option_val $shell.CmdOption + } + AfterAll { + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + } + It 'File copy: <Title> ' -TestCases:$testData { + param([string]$Title, $Source, $Destination, [string]$Options) + iex "scp $Options $Source $Destination" + $LASTEXITCODE | Should Be 0 + #validate file content. DestPath is the path to the file. + CheckTarget -target $DestinationFilePath | Should Be $true + $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 + $equal | Should Be $true + if($Options.contains("-p ") -and [environment]::OSVersion.Version.Major -ge 10) + { + $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0 + $equal | Should Be $true + } + } + } } } } diff --git a/regress/pesterTests/SFTP.Tests.ps1 b/regress/pesterTests/SFTP.Tests.ps1 index d45ad69f2afd..a8362147f936 100644 --- a/regress/pesterTests/SFTP.Tests.ps1 +++ b/regress/pesterTests/SFTP.Tests.ps1 @@ -3,225 +3,223 @@ Import-Module $PSScriptRoot\CommonUtils.psm1 -Force $tI = 0 Describe "SFTP Test Cases" -Tags "CI" { BeforeAll { - $serverDirectory = $null - $clientDirectory = $null - if($OpenSSHTestInfo -eq $null) - { - Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments." - } - - $rootDirectory = "$($OpenSSHTestInfo["TestDataPath"])\SFTP" - - $outputFileName = "output.txt" - $batchFileName = "sftp-batchcmds.txt" - $tempFileName = "tempFile.txt" - $tempFilePath = Join-Path $rootDirectory $tempFileName - - $tempUnicodeFileName = "tempFile_язык.txt" - $tempUnicodeFilePath = Join-Path $rootDirectory $tempUnicodeFileName - - $largeFileName = "largeFile.txt" - $largeFilePath = Join-Path $rootDirectory $largeFileName - fsutil file createNew $filename 1000000000 - - $clientDirectory = Join-Path $rootDirectory 'client_dir' - $serverDirectory = Join-Path $rootDirectory 'server_dir' - - $null = New-Item $clientDirectory -ItemType directory -Force - $null = New-Item $serverDirectory -ItemType directory -Force - $null = New-Item $tempFilePath -ItemType file -Force -value "temp file data" - $null = New-Item $tempUnicodeFilePath -ItemType file -Force -value "temp file data" - - $server = $OpenSSHTestInfo["Target"] - $port = $OpenSSHTestInfo["Port"] - $ssouser = $OpenSSHTestInfo["SSOUser"] - - Remove-item (Join-Path $rootDirectory "*.$outputFileName") -Force -ErrorAction SilentlyContinue - Remove-item (Join-Path $rootDirectory "*.$batchFileName") -Force -ErrorAction SilentlyContinue - Remove-item (Join-Path $rootDirectory "*.log") -Force -ErrorAction SilentlyContinue - - $skip = $IsWindows -and ($PSVersionTable.PSVersion.Major -le 2) - - $testData1 = @( + $serverDirectory = $null + $clientDirectory = $null + if($OpenSSHTestInfo -eq $null) + { + Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments." + } + $rootDirectory = "$($OpenSSHTestInfo["TestDataPath"])\SFTP" + $outputFileName = "output.txt" + $batchFileName = "sftp-batchcmds.txt" + $tempFileName = "tempFile.txt" + $tempFilePath = Join-Path $rootDirectory $tempFileName + $tempUnicodeFileName = "tempFile_язык.txt" + $tempUnicodeFilePath = Join-Path $rootDirectory $tempUnicodeFileName + $largeFileName = "largeFile.txt" + $largeFilePath = Join-Path $rootDirectory $largeFileName + fsutil file createNew $largeFilePath 1000000000 + $clientDirectory = Join-Path $rootDirectory 'client_dir' + $serverDirectory = Join-Path $rootDirectory 'server_dir' + $null = New-Item $clientDirectory -ItemType directory -Force + $null = New-Item $serverDirectory -ItemType directory -Force + $null = New-Item $tempFilePath -ItemType file -Force -value "temp file data" + $null = New-Item $tempUnicodeFilePath -ItemType file -Force -value "temp file data" + $server = $OpenSSHTestInfo["Target"] + $port = $OpenSSHTestInfo["Port"] + $ssouser = $OpenSSHTestInfo["SSOUser"] + Remove-item (Join-Path $rootDirectory "*.$outputFileName") -Force -ErrorAction SilentlyContinue + Remove-item (Join-Path $rootDirectory "*.$batchFileName") -Force -ErrorAction SilentlyContinue + Remove-item (Join-Path $rootDirectory "*.log") -Force -ErrorAction SilentlyContinue + $skip = $IsWindows -and ($PSVersionTable.PSVersion.Major -le 2) + $testData1 = @( + @{ + title = "put, ls for non-unicode file names" + options = '' + commands = "put $tempFilePath $serverDirectory + ls $serverDirectory" + expectedoutput = (join-path $serverdirectory $tempFileName) + }, + @{ + title = "get, ls for non-unicode file names" + options = '' + commands = "get $tempFilePath $clientDirectory + ls $clientDirectory" + expectedoutput = (join-path $clientDirectory $tempFileName) + }, + @{ + title = "mput, ls for non-unicode file names" + options = '' + commands = "mput $tempFilePath $serverDirectory + ls $serverDirectory" + expectedoutput = (join-path $serverdirectory $tempFileName) + }, + @{ + title = "mget, ls for non-unicode file names" + options = '' + commands = "mget $tempFilePath $clientDirectory + ls $clientDirectory" + expectedoutput = (join-path $clientDirectory $tempFileName) + }, + @{ + title = "mkdir, cd, pwd for non-unicode directory names" + options = '' + commands = "cd $serverdirectory + mkdir server_test_dir + cd server_test_dir + pwd" + expectedoutput = (join-path $serverdirectory "server_test_dir") + }, + @{ + Title = "lmkdir, lcd, lpwd for non-unicode directory names" + Options = '' + Commands = "lcd $clientDirectory + lmkdir client_test_dir + lcd client_test_dir + lpwd" + ExpectedOutput = (Join-Path $clientDirectory "client_test_dir") + }, + @{ + title = "put, ls for unicode file names" + options = '' + commands = "put $tempUnicodeFilePath $serverDirectory + ls $serverDirectory" + expectedoutput = (join-path $serverdirectory $tempUnicodeFileName) + }, + @{ + title = "get, ls for unicode file names" + options = '' + commands = "get $tempUnicodeFilePath $clientDirectory + ls $clientDirectory" + expectedoutput = (join-path $clientDirectory $tempUnicodeFileName) + }, + @{ + title = "mput, ls for unicode file names" + options = '' + commands = "mput $tempUnicodeFilePath $serverDirectory + ls $serverDirectory" + expectedoutput = (join-path $serverdirectory $tempUnicodeFileName) + }, + @{ + title = "mget, ls for unicode file names" + options = '' + commands = "mget $tempUnicodeFilePath $clientDirectory + ls $clientDirectory" + expectedoutput = (join-path $clientDirectory $tempUnicodeFileName) + }, + @{ + title = "mkdir, cd, pwd for unicode directory names" + options = '' + commands = "cd $serverdirectory + mkdir server_test_dir_язык + cd server_test_dir_язык + pwd" + expectedoutput = (join-path $serverdirectory "server_test_dir_язык") + }, + @{ + Title = "lmkdir, lcd, lpwd for unicode directory names" + Options = '' + Commands = "lcd $clientDirectory + lmkdir client_test_dir_язык + lcd client_test_dir_язык + lpwd + lls $clientDirectory" + ExpectedOutput = (Join-Path $clientDirectory "client_test_dir_язык") + } + ) + $testData2 = @( @{ - title = "put, ls for non-unicode file names" - options = '' - commands = "put $tempFilePath $serverDirectory - ls $serverDirectory" - expectedoutput = (join-path $serverdirectory $tempFileName) - }, - @{ - title = "get, ls for non-unicode file names" - options = '' - commands = "get $tempFilePath $clientDirectory - ls $clientDirectory" - expectedoutput = (join-path $clientDirectory $tempFileName) - }, - @{ - title = "mput, ls for non-unicode file names" - options = '' - commands = "mput $tempFilePath $serverDirectory - ls $serverDirectory" - expectedoutput = (join-path $serverdirectory $tempFileName) - }, - @{ - title = "mget, ls for non-unicode file names" - options = '' - commands = "mget $tempFilePath $clientDirectory - ls $clientDirectory" - expectedoutput = (join-path $clientDirectory $tempFileName) + title = "rm, rmdir, rename for unicode file, directory" + options = '-b $batchFilePath' + tmpFileName1 = $tempUnicodeFileName + tmpFilePath1 = $tempUnicodeFilePath + tmpFileName2 = "tempfile_язык_2.txt" + tmpFilePath2 = (join-path $serverDirectory "tempfile_язык_2.txt") + tmpDirectoryName1 = "test_dir_язык_1" + tmpDirectoryPath1 = (join-path $serverDirectory "test_dir_язык_1") + tmpDirectoryName2 = "test_dir_язык_2" + tmpDirectoryPath2 = (join-path $serverDirectory "test_dir_язык_2") }, @{ - title = "mkdir, cd, pwd for non-unicode directory names" - options = '' - commands = "cd $serverdirectory - mkdir server_test_dir - cd server_test_dir - pwd" - expectedoutput = (join-path $serverdirectory "server_test_dir") - }, - @{ - Title = "lmkdir, lcd, lpwd for non-unicode directory names" - Options = '' - Commands = "lcd $clientDirectory - lmkdir client_test_dir - lcd client_test_dir - lpwd" - ExpectedOutput = (Join-Path $clientDirectory "client_test_dir") - }, + title = "rm, rmdir, rename for non-unicode file, directory" + options = '-b $batchFilePath' + tmpFileName1 = $tempFileName + tmpFilePath1 = $tempFilePath + tmpFileName2 = "tempfile_2.txt" + tmpFilePath2 = (join-path $serverDirectory "tempfile_2.txt") + tmpDirectoryName1 = "test_dir_1" + tmpDirectoryPath1 = (join-path $serverDirectory "test_dir_1") + tmpDirectoryName2 = "test_dir_2" + tmpDirectoryPath2 = (join-path $serverDirectory "test_dir_2") + } + ) + $testData3 = @( @{ - title = "put, ls for unicode file names" - options = '' - commands = "put $tempUnicodeFilePath $serverDirectory + title = "put, ls for large file transfer" + commands = "put $largeFilePath $serverDirectory ls $serverDirectory" - expectedoutput = (join-path $serverdirectory $tempUnicodeFileName) + expectedoutput = (join-path $serverdirectory $largeFileName) }, @{ - title = "get, ls for unicode file names" - options = '' - commands = "get $tempUnicodeFilePath $clientDirectory + title = "get, ls for large file transfer" + commands = "get $largeFilePath $clientDirectory ls $clientDirectory" - expectedoutput = (join-path $clientDirectory $tempUnicodeFileName) + expectedoutput = (join-path $clientDirectory $largeFileName) }, @{ - title = "mput, ls for unicode file names" - options = '' - commands = "mput $tempUnicodeFilePath $serverDirectory + title = "mput, ls for large file transfer" + commands = "mput $largeFilePath $serverDirectory ls $serverDirectory" - expectedoutput = (join-path $serverdirectory $tempUnicodeFileName) + expectedoutput = (join-path $serverdirectory $largeFileName) }, @{ - title = "mget, ls for unicode file names" - options = '' - commands = "mget $tempUnicodeFilePath $clientDirectory + title = "mget, ls for large file transfer" + commands = "mget $largeFilePath $clientDirectory ls $clientDirectory" - expectedoutput = (join-path $clientDirectory $tempUnicodeFileName) - }, - @{ - title = "mkdir, cd, pwd for unicode directory names" - options = '' - commands = "cd $serverdirectory - mkdir server_test_dir_язык - cd server_test_dir_язык - pwd" - expectedoutput = (join-path $serverdirectory "server_test_dir_язык") - }, - @{ - Title = "lmkdir, lcd, lpwd for unicode directory names" - Options = '' - Commands = "lcd $clientDirectory - lmkdir client_test_dir_язык - lcd client_test_dir_язык - lpwd - lls $clientDirectory" - ExpectedOutput = (Join-Path $clientDirectory "client_test_dir_язык") + expectedoutput = (join-path $clientDirectory $largeFileName) } - ) - - $testData2 = @( - @{ - title = "rm, rmdir, rename for unicode file, directory" - options = '-b $batchFilePath' - - tmpFileName1 = $tempUnicodeFileName - tmpFilePath1 = $tempUnicodeFilePath - tmpFileName2 = "tempfile_язык_2.txt" - tmpFilePath2 = (join-path $serverDirectory "tempfile_язык_2.txt") - - tmpDirectoryName1 = "test_dir_язык_1" - tmpDirectoryPath1 = (join-path $serverDirectory "test_dir_язык_1") - tmpDirectoryName2 = "test_dir_язык_2" - tmpDirectoryPath2 = (join-path $serverDirectory "test_dir_язык_2") - }, - @{ - title = "rm, rmdir, rename for non-unicode file, directory" - options = '-b $batchFilePath' + ) + # for the first time, delete the existing log files. + if ($OpenSSHTestInfo['DebugMode']) + { + Clear-Content "$env:ProgramData\ssh\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue + Clear-Content "$env:ProgramData\ssh\logs\sshd.log" -Force -ErrorAction SilentlyContinue + Clear-Content "$env:ProgramData\ssh\logs\sftp-server.log" -Force -ErrorAction SilentlyContinue + } + function CopyDebugLogs { + if($OpenSSHTestInfo["DebugMode"]) + { + Copy-Item "$env:ProgramData\ssh\logs\ssh-agent.log" "$rootDirectory\ssh-agent_$tI.log" -Force -ErrorAction SilentlyContinue + Copy-Item "$env:ProgramData\ssh\logs\sshd.log" "$rootDirectory\sshd_$tI.log" -Force -ErrorAction SilentlyContinue + Copy-Item "$env:ProgramData\ssh\logs\sftp-server.log" "$rootDirectory\sftp-server_$tI.log" -Force -ErrorAction SilentlyContinue + # clear the ssh-agent, sshd logs so that next testcase will get fresh logs. + Clear-Content "$env:ProgramData\ssh\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue + Clear-Content "$env:ProgramData\ssh\logs\sshd.log" -Force -ErrorAction SilentlyContinue + Clear-Content "$env:ProgramData\ssh\logs\sftp-server.log" -Force -ErrorAction SilentlyContinue + } + } - tmpFileName1 = $tempFileName - tmpFilePath1 = $tempFilePath - tmpFileName2 = "tempfile_2.txt" - tmpFilePath2 = (join-path $serverDirectory "tempfile_2.txt") + function ConfigureDefaultShell { + param + ( + [string] $default_shell_path, + [string] $default_shell_cmd_option_val = $null + ) - tmpDirectoryName1 = "test_dir_1" - tmpDirectoryPath1 = (join-path $serverDirectory "test_dir_1") - tmpDirectoryName2 = "test_dir_2" - tmpDirectoryPath2 = (join-path $serverDirectory "test_dir_2") + if (!(Test-Path $dfltShellRegPath)) { + New-Item -Path $dfltShellRegPath -Force | Out-Null } - ) - - $testData3 = @( - @{ - title = "put, ls for large file transfer" - commands = "put $largeFilePath $serverDirectory - ls $serverDirectory" - expectedoutput = (join-path $serverdirectory $largeFileName) - }, - @{ - title = "get, ls for large file transfer" - commands = "get $largeFilePath $clientDirectory - ls $clientDirectory" - expectedoutput = (join-path $clientDirectory $largeFileName) - }, - @{ - title = "mput, ls for large file transfer" - commands = "mput $largeFilePath $serverDirectory - ls $serverDirectory" - expectedoutput = (join-path $serverdirectory $largeFileName) - }, - @{ - title = "mget, ls for large file transfer" - commands = "mget $largeFilePath $clientDirectory - ls $clientDirectory" - expectedoutput = (join-path $clientDirectory $largeFileName) + New-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -Value $default_shell_path -PropertyType String -Force + if ($default_shell_cmd_option_val -ne $null) { + New-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -Value $default_shell_cmd_option_val -PropertyType String -Force } - ) - - # for the first time, delete the existing log files. - if ($OpenSSHTestInfo['DebugMode']) - { - Clear-Content "$env:ProgramData\ssh\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue - Clear-Content "$env:ProgramData\ssh\logs\sshd.log" -Force -ErrorAction SilentlyContinue - Clear-Content "$env:ProgramData\ssh\logs\sftp-server.log" -Force -ErrorAction SilentlyContinue - } - - function CopyDebugLogs { - if($OpenSSHTestInfo["DebugMode"]) - { - Copy-Item "$env:ProgramData\ssh\logs\ssh-agent.log" "$rootDirectory\ssh-agent_$tI.log" -Force -ErrorAction SilentlyContinue - Copy-Item "$env:ProgramData\ssh\logs\sshd.log" "$rootDirectory\sshd_$tI.log" -Force -ErrorAction SilentlyContinue - Copy-Item "$env:ProgramData\ssh\logs\sftp-server.log" "$rootDirectory\sftp-server_$tI.log" -Force -ErrorAction SilentlyContinue - - # clear the ssh-agent, sshd logs so that next testcase will get fresh logs. - Clear-Content "$env:ProgramData\ssh\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue - Clear-Content "$env:ProgramData\ssh\logs\sshd.log" -Force -ErrorAction SilentlyContinue - Clear-Content "$env:ProgramData\ssh\logs\sftp-server.log" -Force -ErrorAction SilentlyContinue - } - } + } } AfterAll { if($serverDirectory) { Get-ChildItem $serverDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue } if($clientDirectory) { Get-ChildItem $clientDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue } + if(Test-Path $largeFilePath) { Remove-Item $largeFilePath -Force -ErrorAction SilentlyContinue } } BeforeEach { @@ -342,4 +340,68 @@ Describe "SFTP Test Cases" -Tags "CI" { Test-Path $ExpectedOutput | Should be $true $LASTEXITCODE | Should Be 0 } + + Context "Configure various default shell scenarios" { + BeforeAll { + $dfltShellRegPath = "HKLM:\Software\OpenSSH" + $dfltShellRegKeyName = "DefaultShell" + $dfltShellCmdOptionRegKeyName = "DefaultShellCommandOption" + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + } + + AfterAll { + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + } + + $shells = @( + @{ + Name = "Windows PowerShell" + Path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).Path + CmdOption = "/c" + }, + @{ + Name = "PowerShell Core" + Path = (Get-Command pwsh -ErrorAction SilentlyContinue).Path + CmdOption = $null + }, + @{ + Name = "Bash" + Path = (Get-Command bash -ErrorAction SilentlyContinue).Path + CmdOption = $null + }, + @{ + Name = "Cygwin" + Path = (Get-Command sh -ErrorAction SilentlyContinue).Path + CmdOption = $null + } + ) + + foreach ($shell in $shells) { + if ($shell.Path -ne $null) { + Context "Configure default shell as $($shell.Name)" { + BeforeAll { + ConfigureDefaultShell -default_shell_path $shell.Path -default_shell_cmd_option_val $shell.CmdOption + } + + AfterAll { + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + } + + It "<Title> for $($shell.Name)" -TestCases:$testData1 -Skip:($shell.Path -eq $null) -SkipReason "Shell path not found" { + param([string]$Title, $Options, $Commands, $ExpectedOutput) + + Set-Content $batchFilePath -Encoding UTF8 -value $Commands + $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) -b $batchFilePath test_target > $outputFilePath") + iex $str + + #validate file content. + Test-Path $ExpectedOutput | Should be $true + } + } + } + } + } } From dbc5bf4e652be2a324c04b8b4c0f11e1b34dae29 Mon Sep 17 00:00:00 2001 From: Tess Gauthier <tessgauthier@microsoft.com> Date: Tue, 29 Apr 2025 15:09:12 -0400 Subject: [PATCH 03/13] fix syntax --- regress/pesterTests/SCP.Tests.ps1 | 4 ---- regress/pesterTests/SFTP.Tests.ps1 | 5 +++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/regress/pesterTests/SCP.Tests.ps1 b/regress/pesterTests/SCP.Tests.ps1 index 81561b1d2dd5..4bb910a7836c 100644 --- a/regress/pesterTests/SCP.Tests.ps1 +++ b/regress/pesterTests/SCP.Tests.ps1 @@ -232,10 +232,6 @@ Describe "Tests for scp command" -Tags "CI" { } } - BeforeAll { - $null = New-Item $DestinationDir -ItemType directory -Force -ErrorAction SilentlyContinue - } - AfterEach { Get-ChildItem $DestinationDir -Recurse | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Start-Sleep 1 diff --git a/regress/pesterTests/SFTP.Tests.ps1 b/regress/pesterTests/SFTP.Tests.ps1 index a8362147f936..443c947da01a 100644 --- a/regress/pesterTests/SFTP.Tests.ps1 +++ b/regress/pesterTests/SFTP.Tests.ps1 @@ -5,6 +5,7 @@ Describe "SFTP Test Cases" -Tags "CI" { BeforeAll { $serverDirectory = $null $clientDirectory = $null + $largeFilePath = $null if($OpenSSHTestInfo -eq $null) { Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments." @@ -219,7 +220,7 @@ Describe "SFTP Test Cases" -Tags "CI" { AfterAll { if($serverDirectory) { Get-ChildItem $serverDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue } if($clientDirectory) { Get-ChildItem $clientDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue } - if(Test-Path $largeFilePath) { Remove-Item $largeFilePath -Force -ErrorAction SilentlyContinue } + if($largeFilePath) { Remove-Item $largeFilePath -Force -ErrorAction SilentlyContinue } } BeforeEach { @@ -390,7 +391,7 @@ Describe "SFTP Test Cases" -Tags "CI" { Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue } - It "<Title> for $($shell.Name)" -TestCases:$testData1 -Skip:($shell.Path -eq $null) -SkipReason "Shell path not found" { + It "<Title> for $($shell.Name)" -TestCases:$testData1 -Skip:($shell.Path -eq $null) { param([string]$Title, $Options, $Commands, $ExpectedOutput) Set-Content $batchFilePath -Encoding UTF8 -value $Commands From 0713c59a5dcc91d727141148e7e2f7cb4ed3cc12 Mon Sep 17 00:00:00 2001 From: Tess Gauthier <tessgauthier@microsoft.com> Date: Wed, 30 Apr 2025 12:51:58 -0400 Subject: [PATCH 04/13] fix scp test --- regress/pesterTests/SCP.Tests.ps1 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/regress/pesterTests/SCP.Tests.ps1 b/regress/pesterTests/SCP.Tests.ps1 index 4bb910a7836c..c3445dbad1ab 100644 --- a/regress/pesterTests/SCP.Tests.ps1 +++ b/regress/pesterTests/SCP.Tests.ps1 @@ -164,6 +164,7 @@ Describe "Tests for scp command" -Tags "CI" { Title = 'copy large file from remote dir to local dir' Source = "test_target:$largeFilePath" Destination = $DestinationDir + Options = "-p -c aes128-ctr -C" } ) @@ -314,14 +315,11 @@ Describe "Tests for scp command" -Tags "CI" { iex "scp $Options $Source $Destination" $LASTEXITCODE | Should Be 0 - $DestinationFilePath = Join-Path $Destination $largeFileName + $DestinationFilePath = Join-Path $DestinationDir $largeFileName CheckTarget -target $DestinationFilePath | Should Be $true $equal = @(Compare-Object (Get-ChildItem -path $Source) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 $equal | Should Be $true - - $equal = @(Compare-Object (Get-ChildItem -path $Source).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0 - $equal | Should Be $true } } From 0d7b3ceff9f8b5bee4cfb03635633efd97ae97eb Mon Sep 17 00:00:00 2001 From: User <tessgauthier@microsoft.com> Date: Wed, 30 Apr 2025 11:03:06 -0700 Subject: [PATCH 05/13] refactor default shell tests --- regress/pesterTests/SCP.Tests.ps1 | 104 ++++++++++++-------------- regress/pesterTests/SFTP.Tests.ps1 | 113 ++++++++++++++--------------- regress/pesterTests/SSH.Tests.ps1 | 10 ++- 3 files changed, 108 insertions(+), 119 deletions(-) diff --git a/regress/pesterTests/SCP.Tests.ps1 b/regress/pesterTests/SCP.Tests.ps1 index c3445dbad1ab..51581ae25d8e 100644 --- a/regress/pesterTests/SCP.Tests.ps1 +++ b/regress/pesterTests/SCP.Tests.ps1 @@ -325,66 +325,58 @@ Describe "Tests for scp command" -Tags "CI" { Context "Configure various default shell scenarios" { BeforeAll { - $dfltShellRegPath = "HKLM:\Software\OpenSSH" - $dfltShellRegKeyName = "DefaultShell" - $dfltShellCmdOptionRegKeyName = "DefaultShellCommandOption" - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + $dfltShellRegPath = $null + $dfltShellRegPath = "HKLM:\Software\OpenSSH" + $dfltShellRegKeyName = "DefaultShell" + $dfltShellCmdOptionRegKeyName = "DefaultShellCommandOption" + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + $shells = @( + @{ + Name = "Windows PowerShell" + Path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).Path + CmdOption = "/c" + }, + @{ + Name = "PowerShell Core" + Path = (Get-Command pwsh -ErrorAction SilentlyContinue).Path + CmdOption = $null + }, + @{ + Name = "Bash" + Path = (Get-Command bash -ErrorAction SilentlyContinue).Path + CmdOption = $null + }, + @{ + Name = "Cygwin" + Path = (Get-Command sh -ErrorAction SilentlyContinue).Path + CmdOption = $null + } + ) } - AfterAll { - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + AfterEach { + if ($dfltShellRegPath) { + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + } } - $shells = @( - @{ - Name = "Windows PowerShell" - Path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).Path - CmdOption = "/c" - }, - @{ - Name = "PowerShell Core" - Path = (Get-Command pwsh -ErrorAction SilentlyContinue).Path - CmdOption = $null - }, - @{ - Name = "Bash" - Path = (Get-Command bash -ErrorAction SilentlyContinue).Path - CmdOption = $null - }, - @{ - Name = "Cygwin" - Path = (Get-Command sh -ErrorAction SilentlyContinue).Path - CmdOption = $null - } - ) - - foreach ($shell in $shells) { - if ($shell.Path -ne $null) { - Context "Configure default shell as $($shell.Name)" { - BeforeAll { - ConfigureDefaultShell -default_shell_path $shell.Path -default_shell_cmd_option_val $shell.CmdOption - } - AfterAll { - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue - } - It 'File copy: <Title> ' -TestCases:$testData { - param([string]$Title, $Source, $Destination, [string]$Options) - iex "scp $Options $Source $Destination" - $LASTEXITCODE | Should Be 0 - #validate file content. DestPath is the path to the file. - CheckTarget -target $DestinationFilePath | Should Be $true - $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 - $equal | Should Be $true - if($Options.contains("-p ") -and [environment]::OSVersion.Version.Major -ge 10) - { - $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0 - $equal | Should Be $true - } - } - } + It 'File copy: <Name> ' -TestCases:$shells { + param([string]$Name, $Path, $CmdOption) + if ($Path -eq $null) { + throw "$Name not found, please install it to run this test" + } + else { + ConfigureDefaultShell -default_shell_path $Path -default_shell_cmd_option_val $CmdOption + iex "scp test_target:$SourceFilePath $DestinationDir" + $LASTEXITCODE | Should Be 0 + #validate file content. DestPath is the path to the file. + $DestinationFilePath = Join-Path $DestinationDir $fileName1 + CheckTarget -target $DestinationFilePath | Should Be $true + + $equal = @(Compare-Object (Get-ChildItem -path $Source) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 + $equal | Should Be $true } } } diff --git a/regress/pesterTests/SFTP.Tests.ps1 b/regress/pesterTests/SFTP.Tests.ps1 index 443c947da01a..79cb6489b240 100644 --- a/regress/pesterTests/SFTP.Tests.ps1 +++ b/regress/pesterTests/SFTP.Tests.ps1 @@ -342,67 +342,62 @@ Describe "SFTP Test Cases" -Tags "CI" { $LASTEXITCODE | Should Be 0 } - Context "Configure various default shell scenarios" { - BeforeAll { - $dfltShellRegPath = "HKLM:\Software\OpenSSH" - $dfltShellRegKeyName = "DefaultShell" - $dfltShellCmdOptionRegKeyName = "DefaultShellCommandOption" - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue - } - - AfterAll { - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue - } - - $shells = @( - @{ - Name = "Windows PowerShell" - Path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).Path - CmdOption = "/c" - }, - @{ - Name = "PowerShell Core" - Path = (Get-Command pwsh -ErrorAction SilentlyContinue).Path - CmdOption = $null - }, - @{ - Name = "Bash" - Path = (Get-Command bash -ErrorAction SilentlyContinue).Path - CmdOption = $null - }, - @{ - Name = "Cygwin" - Path = (Get-Command sh -ErrorAction SilentlyContinue).Path - CmdOption = $null - } - ) - - foreach ($shell in $shells) { - if ($shell.Path -ne $null) { - Context "Configure default shell as $($shell.Name)" { - BeforeAll { - ConfigureDefaultShell -default_shell_path $shell.Path -default_shell_cmd_option_val $shell.CmdOption - } - - AfterAll { - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue - Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue - } + Context "Configure various default shell scenarios" { + BeforeAll { + $dfltShellRegPath = $null + $dfltShellRegPath = "HKLM:\Software\OpenSSH" + $dfltShellRegKeyName = "DefaultShell" + $dfltShellCmdOptionRegKeyName = "DefaultShellCommandOption" + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + $shells = @( + @{ + Name = "Windows PowerShell" + Path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).Path + CmdOption = "/c" + }, + @{ + Name = "PowerShell Core" + Path = (Get-Command pwsh -ErrorAction SilentlyContinue).Path + CmdOption = $null + }, + @{ + Name = "Bash" + Path = (Get-Command bash -ErrorAction SilentlyContinue).Path + CmdOption = $null + }, + @{ + Name = "Cygwin" + Path = (Get-Command sh -ErrorAction SilentlyContinue).Path + CmdOption = $null + } + ) + } - It "<Title> for $($shell.Name)" -TestCases:$testData1 -Skip:($shell.Path -eq $null) { - param([string]$Title, $Options, $Commands, $ExpectedOutput) + AfterEach { + if ($dfltShellRegPath) { + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue + Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue + } + } - Set-Content $batchFilePath -Encoding UTF8 -value $Commands - $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) -b $batchFilePath test_target > $outputFilePath") - iex $str + It 'File copy: <Name> ' -TestCases:$shells { + param([string]$Name, $Path, $CmdOptions) + if ($Path -eq $null) { + throw "$Name not found, please install it to run this test" + } + else { + ConfigureDefaultShell -default_shell_path $Path -default_shell_cmd_option_val $CmdOption + $Commands = "put $tempFilePath $serverDirectory + ls $serverDirectory" + Set-Content $batchFilePath -Encoding UTF8 -value $Commands + $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) -b $batchFilePath test_target > $outputFilePath") + iex $str - #validate file content. - Test-Path $ExpectedOutput | Should be $true - } + #validate file content. + $ExpectedOutput = (join-path $serverdirectory $tempFileName) + Test-Path $ExpectedOutput | Should be $true } - } - } - } + } + } } diff --git a/regress/pesterTests/SSH.Tests.ps1 b/regress/pesterTests/SSH.Tests.ps1 index 205b860fc5b4..71e4d412536d 100644 --- a/regress/pesterTests/SSH.Tests.ps1 +++ b/regress/pesterTests/SSH.Tests.ps1 @@ -407,13 +407,15 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { } It "$tC.$tI - force pseudo-terminal allocation (-t)" { - $o = ssh -t test_target echo 1234 - $o | Should Be "1234" + ssh -t -E $logFile test_target whoami + $LASTEXITCODE | Should Be 0 + $logFile | Should Contain $ssouser } It "$tC.$tI - disable pseudo-terminal allocation (-T)" { - $o = ssh -T test_target echo 1234 - $o | Should Be "1234" + ssh -E $logFile test_target whoami + $LASTEXITCODE | Should Be 0 + $logFile | Should Contain $ssouser } } } From c1bde80e2bcab493852185bf48947ab1dd0a203e Mon Sep 17 00:00:00 2001 From: User <tessgauthier@microsoft.com> Date: Wed, 30 Apr 2025 13:05:43 -0700 Subject: [PATCH 06/13] fix typos --- regress/pesterTests/SCP.Tests.ps1 | 4 ++-- regress/pesterTests/SFTP.Tests.ps1 | 10 ++++++---- regress/pesterTests/SSH.Tests.ps1 | 9 +++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/regress/pesterTests/SCP.Tests.ps1 b/regress/pesterTests/SCP.Tests.ps1 index 51581ae25d8e..ed72177637af 100644 --- a/regress/pesterTests/SCP.Tests.ps1 +++ b/regress/pesterTests/SCP.Tests.ps1 @@ -318,7 +318,7 @@ Describe "Tests for scp command" -Tags "CI" { $DestinationFilePath = Join-Path $DestinationDir $largeFileName CheckTarget -target $DestinationFilePath | Should Be $true - $equal = @(Compare-Object (Get-ChildItem -path $Source) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 + $equal = @(Compare-Object (Get-ChildItem -path $largeFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 $equal | Should Be $true } } @@ -375,7 +375,7 @@ Describe "Tests for scp command" -Tags "CI" { $DestinationFilePath = Join-Path $DestinationDir $fileName1 CheckTarget -target $DestinationFilePath | Should Be $true - $equal = @(Compare-Object (Get-ChildItem -path $Source) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 + $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0 $equal | Should Be $true } } diff --git a/regress/pesterTests/SFTP.Tests.ps1 b/regress/pesterTests/SFTP.Tests.ps1 index 79cb6489b240..7ba9184dd647 100644 --- a/regress/pesterTests/SFTP.Tests.ps1 +++ b/regress/pesterTests/SFTP.Tests.ps1 @@ -331,13 +331,14 @@ Describe "SFTP Test Cases" -Tags "CI" { } It '<Title>' -TestCases:$testData3 { - param([string]$Title, $Options, $Commands, $ExpectedOutput) + param([string]$Title, $Commands, $ExpectedOutput) Set-Content $batchFilePath -Encoding UTF8 -value $Commands - $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) -b $batchFilePath test_target > $outputFilePath") + $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port -b $batchFilePath test_target > $outputFilePath") iex $str #validate file content. + Get-Content $outputFilePath | Write-Host Test-Path $ExpectedOutput | Should be $true $LASTEXITCODE | Should Be 0 } @@ -382,7 +383,7 @@ Describe "SFTP Test Cases" -Tags "CI" { } It 'File copy: <Name> ' -TestCases:$shells { - param([string]$Name, $Path, $CmdOptions) + param([string]$Name, $Path, $CmdOption) if ($Path -eq $null) { throw "$Name not found, please install it to run this test" } @@ -391,10 +392,11 @@ Describe "SFTP Test Cases" -Tags "CI" { $Commands = "put $tempFilePath $serverDirectory ls $serverDirectory" Set-Content $batchFilePath -Encoding UTF8 -value $Commands - $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) -b $batchFilePath test_target > $outputFilePath") + $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port -b $batchFilePath test_target > $outputFilePath") iex $str #validate file content. + Get-Content $outputFilePath | Write-Host $ExpectedOutput = (join-path $serverdirectory $tempFileName) Test-Path $ExpectedOutput | Should be $true } diff --git a/regress/pesterTests/SSH.Tests.ps1 b/regress/pesterTests/SSH.Tests.ps1 index 71e4d412536d..eda3ddb7ce65 100644 --- a/regress/pesterTests/SSH.Tests.ps1 +++ b/regress/pesterTests/SSH.Tests.ps1 @@ -407,15 +407,16 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { } It "$tC.$tI - force pseudo-terminal allocation (-t)" { - ssh -t -E $logFile test_target whoami + $o = ssh -t test_target echo 1234 $LASTEXITCODE | Should Be 0 - $logFile | Should Contain $ssouser + $o.Length | Should Be 2 + $o[0].Contains("1234") | Should Be $true } It "$tC.$tI - disable pseudo-terminal allocation (-T)" { - ssh -E $logFile test_target whoami + $o = ssh -T test_target whoami $LASTEXITCODE | Should Be 0 - $logFile | Should Contain $ssouser + $o | Should Be "1234" } } } From 2fe4efaa3eea7ede580acd027f39cbef6b1288b6 Mon Sep 17 00:00:00 2001 From: User <tessgauthier@microsoft.com> Date: Wed, 30 Apr 2025 13:52:05 -0700 Subject: [PATCH 07/13] fix ssh tests --- regress/pesterTests/SFTP.Tests.ps1 | 11 ++++++----- regress/pesterTests/SSH.Tests.ps1 | 3 +-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/regress/pesterTests/SFTP.Tests.ps1 b/regress/pesterTests/SFTP.Tests.ps1 index 7ba9184dd647..4746a434b263 100644 --- a/regress/pesterTests/SFTP.Tests.ps1 +++ b/regress/pesterTests/SFTP.Tests.ps1 @@ -237,7 +237,6 @@ Describe "SFTP Test Cases" -Tags "CI" { It '<Title>' -TestCases:$testData1 { param([string]$Title, $Options, $Commands, $ExpectedOutput) - Set-Content $batchFilePath -Encoding UTF8 -value $Commands $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) -b $batchFilePath test_target > $outputFilePath") iex $str @@ -332,11 +331,14 @@ Describe "SFTP Test Cases" -Tags "CI" { It '<Title>' -TestCases:$testData3 { param([string]$Title, $Commands, $ExpectedOutput) - + if (-not (Test-Path $largeFilePath)) { + write-host "creating large file because it did not exist" + fsutil file createNew $largeFilePath 1000000000 + } Set-Content $batchFilePath -Encoding UTF8 -value $Commands - $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port -b $batchFilePath test_target > $outputFilePath") + $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -vvv -P $port -b $batchFilePath test_target 1>&2 $outputFilePath") iex $str - + Write-Host "Last exit code: $LASTEXITCODE" #validate file content. Get-Content $outputFilePath | Write-Host Test-Path $ExpectedOutput | Should be $true @@ -396,7 +398,6 @@ Describe "SFTP Test Cases" -Tags "CI" { iex $str #validate file content. - Get-Content $outputFilePath | Write-Host $ExpectedOutput = (join-path $serverdirectory $tempFileName) Test-Path $ExpectedOutput | Should be $true } diff --git a/regress/pesterTests/SSH.Tests.ps1 b/regress/pesterTests/SSH.Tests.ps1 index eda3ddb7ce65..c2de462a2d38 100644 --- a/regress/pesterTests/SSH.Tests.ps1 +++ b/regress/pesterTests/SSH.Tests.ps1 @@ -409,12 +409,11 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { It "$tC.$tI - force pseudo-terminal allocation (-t)" { $o = ssh -t test_target echo 1234 $LASTEXITCODE | Should Be 0 - $o.Length | Should Be 2 $o[0].Contains("1234") | Should Be $true } It "$tC.$tI - disable pseudo-terminal allocation (-T)" { - $o = ssh -T test_target whoami + $o = ssh -T test_target echo 1234 $LASTEXITCODE | Should Be 0 $o | Should Be "1234" } From 401a0ca85b0575e4426908fe7b28999f759bcf25 Mon Sep 17 00:00:00 2001 From: User <tessgauthier@microsoft.com> Date: Wed, 30 Apr 2025 14:19:45 -0700 Subject: [PATCH 08/13] fix sftp tests --- regress/pesterTests/SFTP.Tests.ps1 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/regress/pesterTests/SFTP.Tests.ps1 b/regress/pesterTests/SFTP.Tests.ps1 index 4746a434b263..1882ab22a2cd 100644 --- a/regress/pesterTests/SFTP.Tests.ps1 +++ b/regress/pesterTests/SFTP.Tests.ps1 @@ -332,13 +332,12 @@ Describe "SFTP Test Cases" -Tags "CI" { It '<Title>' -TestCases:$testData3 { param([string]$Title, $Commands, $ExpectedOutput) if (-not (Test-Path $largeFilePath)) { - write-host "creating large file because it did not exist" fsutil file createNew $largeFilePath 1000000000 } Set-Content $batchFilePath -Encoding UTF8 -value $Commands - $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -vvv -P $port -b $batchFilePath test_target 1>&2 $outputFilePath") + $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port -b $batchFilePath test_target > $outputFilePath") iex $str - Write-Host "Last exit code: $LASTEXITCODE" + #validate file content. Get-Content $outputFilePath | Write-Host Test-Path $ExpectedOutput | Should be $true From 5c6a80b5889612e71c8190fc320517d4a3c1d9f7 Mon Sep 17 00:00:00 2001 From: Tess Gauthier <tessgauthier@microsoft.com> Date: Thu, 1 May 2025 10:43:23 -0400 Subject: [PATCH 09/13] fix ssh test --- regress/pesterTests/SSH.Tests.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/regress/pesterTests/SSH.Tests.ps1 b/regress/pesterTests/SSH.Tests.ps1 index c2de462a2d38..6c853cabe3b0 100644 --- a/regress/pesterTests/SSH.Tests.ps1 +++ b/regress/pesterTests/SSH.Tests.ps1 @@ -408,8 +408,9 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { It "$tC.$tI - force pseudo-terminal allocation (-t)" { $o = ssh -t test_target echo 1234 + Write-Host "o: $o" $LASTEXITCODE | Should Be 0 - $o[0].Contains("1234") | Should Be $true + $o | Should Be "1234" } It "$tC.$tI - disable pseudo-terminal allocation (-T)" { From 5b53ca5403b537618823242d486e67e3450397c9 Mon Sep 17 00:00:00 2001 From: Tess Gauthier <tessgauthier@microsoft.com> Date: Thu, 1 May 2025 11:37:27 -0400 Subject: [PATCH 10/13] move force pty test to separate pester test file --- regress/pesterTests/SFTP.Tests.ps1 | 5 ++- regress/pesterTests/SSH.Tests.ps1 | 5 ++- regress/pesterTests/Terminal.Tests.ps1 | 42 ++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 regress/pesterTests/Terminal.Tests.ps1 diff --git a/regress/pesterTests/SFTP.Tests.ps1 b/regress/pesterTests/SFTP.Tests.ps1 index 1882ab22a2cd..400778bc8d01 100644 --- a/regress/pesterTests/SFTP.Tests.ps1 +++ b/regress/pesterTests/SFTP.Tests.ps1 @@ -339,7 +339,6 @@ Describe "SFTP Test Cases" -Tags "CI" { iex $str #validate file content. - Get-Content $outputFilePath | Write-Host Test-Path $ExpectedOutput | Should be $true $LASTEXITCODE | Should Be 0 } @@ -377,7 +376,7 @@ Describe "SFTP Test Cases" -Tags "CI" { } AfterEach { - if ($dfltShellRegPath) { + if ($dfltShellRegPath) { Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellRegKeyName -ErrorAction SilentlyContinue Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue } @@ -387,7 +386,7 @@ Describe "SFTP Test Cases" -Tags "CI" { param([string]$Name, $Path, $CmdOption) if ($Path -eq $null) { throw "$Name not found, please install it to run this test" - } + } else { ConfigureDefaultShell -default_shell_path $Path -default_shell_cmd_option_val $CmdOption $Commands = "put $tempFilePath $serverDirectory diff --git a/regress/pesterTests/SSH.Tests.ps1 b/regress/pesterTests/SSH.Tests.ps1 index 6c853cabe3b0..80e452f1893f 100644 --- a/regress/pesterTests/SSH.Tests.ps1 +++ b/regress/pesterTests/SSH.Tests.ps1 @@ -406,11 +406,10 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { $stderrFile | Should Contain "test string for invalid proxy" } - It "$tC.$tI - force pseudo-terminal allocation (-t)" { + It "$tC.$tI - force pseudo-terminal allocation (-t) if run from terminal" -Skip:($Host.UI.RawUI -eq $null) { $o = ssh -t test_target echo 1234 - Write-Host "o: $o" $LASTEXITCODE | Should Be 0 - $o | Should Be "1234" + $o[0].Contains("1234") | Should Be $true } It "$tC.$tI - disable pseudo-terminal allocation (-T)" { diff --git a/regress/pesterTests/Terminal.Tests.ps1 b/regress/pesterTests/Terminal.Tests.ps1 new file mode 100644 index 000000000000..ff8246641f7e --- /dev/null +++ b/regress/pesterTests/Terminal.Tests.ps1 @@ -0,0 +1,42 @@ +If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path} +Import-Module $PSScriptRoot\CommonUtils.psm1 -Force + +$tC = 1 +$tI = 0 +$suite = "sshclientterminal" + +Describe "E2E scenarios for an interactive terminal" -Tags "CI" { + BeforeAll { + if($OpenSSHTestInfo -eq $null) + { + Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments." + } + + $testDir = Join-Path $OpenSSHTestInfo["TestDataPath"] $suite + if(-not (Test-Path $testDir)) + { + $null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue + } + $acl = Get-Acl $testDir + $rights = [System.Security.AccessControl.FileSystemRights]"Read, Write" + $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($ssouser, $rights, "ContainerInherit,Objectinherit", "None", "Allow") + $acl.SetAccessRule($accessRule) + Set-Acl -Path $testDir -AclObject $acl + #skip if non-interactive session + $skip = $Host.UI.RawUI -eq $null + } + + AfterEach {$tI++;} + + Context "$tC - Basic Scenarios" { + + BeforeAll {$tI=1} + AfterAll{$tC++} + + It "$tC.$tI - force pseudo-terminal allocation (-t)" -Skip:$skip { + $o = ssh -t test_target echo 1234 + $LASTEXITCODE | Should Be 0 + $o[0].Contains("1234") | Should Be $true + } + } +} From 44910d8df0035cea59ee1c18a81104650caf0a1e Mon Sep 17 00:00:00 2001 From: User <tessgauthier@microsoft.com> Date: Thu, 1 May 2025 08:55:47 -0700 Subject: [PATCH 11/13] fix initialization --- regress/pesterTests/Terminal.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regress/pesterTests/Terminal.Tests.ps1 b/regress/pesterTests/Terminal.Tests.ps1 index ff8246641f7e..2edfd4fab5bf 100644 --- a/regress/pesterTests/Terminal.Tests.ps1 +++ b/regress/pesterTests/Terminal.Tests.ps1 @@ -11,7 +11,7 @@ Describe "E2E scenarios for an interactive terminal" -Tags "CI" { { Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments." } - + $ssouser = $OpenSSHTestInfo["SSOUser"] $testDir = Join-Path $OpenSSHTestInfo["TestDataPath"] $suite if(-not (Test-Path $testDir)) { From b86814dcc1e019ceb0df87966ba8e94b5bd680a2 Mon Sep 17 00:00:00 2001 From: Tess Gauthier <tessgauthier@microsoft.com> Date: Thu, 1 May 2025 12:05:57 -0400 Subject: [PATCH 12/13] Update SSH.Tests.ps1 --- regress/pesterTests/SSH.Tests.ps1 | 6 ------ 1 file changed, 6 deletions(-) diff --git a/regress/pesterTests/SSH.Tests.ps1 b/regress/pesterTests/SSH.Tests.ps1 index 80e452f1893f..c545c9bffac4 100644 --- a/regress/pesterTests/SSH.Tests.ps1 +++ b/regress/pesterTests/SSH.Tests.ps1 @@ -406,12 +406,6 @@ Describe "E2E scenarios for ssh client" -Tags "CI" { $stderrFile | Should Contain "test string for invalid proxy" } - It "$tC.$tI - force pseudo-terminal allocation (-t) if run from terminal" -Skip:($Host.UI.RawUI -eq $null) { - $o = ssh -t test_target echo 1234 - $LASTEXITCODE | Should Be 0 - $o[0].Contains("1234") | Should Be $true - } - It "$tC.$tI - disable pseudo-terminal allocation (-T)" { $o = ssh -T test_target echo 1234 $LASTEXITCODE | Should Be 0 From e96bec5c29924f5bfd765c21b52f0be5f4e8d6b8 Mon Sep 17 00:00:00 2001 From: User <tessgauthier@microsoft.com> Date: Thu, 1 May 2025 11:55:49 -0700 Subject: [PATCH 13/13] fix skip parameter --- regress/pesterTests/Terminal.Tests.ps1 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/regress/pesterTests/Terminal.Tests.ps1 b/regress/pesterTests/Terminal.Tests.ps1 index 2edfd4fab5bf..36b6bf27a725 100644 --- a/regress/pesterTests/Terminal.Tests.ps1 +++ b/regress/pesterTests/Terminal.Tests.ps1 @@ -1,3 +1,8 @@ +param( + #skip if non-interactive session + [bool]$Skip=$true + ) + If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path} Import-Module $PSScriptRoot\CommonUtils.psm1 -Force @@ -22,8 +27,6 @@ Describe "E2E scenarios for an interactive terminal" -Tags "CI" { $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($ssouser, $rights, "ContainerInherit,Objectinherit", "None", "Allow") $acl.SetAccessRule($accessRule) Set-Acl -Path $testDir -AclObject $acl - #skip if non-interactive session - $skip = $Host.UI.RawUI -eq $null } AfterEach {$tI++;} @@ -33,7 +36,7 @@ Describe "E2E scenarios for an interactive terminal" -Tags "CI" { BeforeAll {$tI=1} AfterAll{$tC++} - It "$tC.$tI - force pseudo-terminal allocation (-t)" -Skip:$skip { + It "$tC.$tI - force pseudo-terminal allocation (-t)" -Skip:$Skip { $o = ssh -t test_target echo 1234 $LASTEXITCODE | Should Be 0 $o[0].Contains("1234") | Should Be $true