2020-03-24 11:08:37 -07:00
|
|
|
# Copyright (c) Microsoft Corporation.
|
2018-02-13 09:23:53 -08:00
|
|
|
# Licensed under the MIT License.
|
2017-09-29 16:28:15 -07:00
|
|
|
Describe "Native streams behavior with PowerShell" -Tags 'CI' {
|
2020-01-05 12:17:41 +05:00
|
|
|
BeforeAll {
|
2020-01-13 19:35:33 +00:00
|
|
|
$powershell = Join-Path -Path $PSHOME -ChildPath "pwsh"
|
2020-01-05 12:17:41 +05:00
|
|
|
}
|
2017-09-29 16:28:15 -07:00
|
|
|
|
|
|
|
|
Context "Error stream" {
|
|
|
|
|
# we are using powershell itself as an example of a native program.
|
|
|
|
|
# we can create a behavior we want on the fly and test complex scenarios.
|
|
|
|
|
|
|
|
|
|
$error.Clear()
|
|
|
|
|
|
|
|
|
|
$command = [string]::Join('', @(
|
2021-04-01 14:54:10 -07:00
|
|
|
'[Console]::Error.Write("foo`n`nbar`n`nbaz"); ',
|
|
|
|
|
'[Console]::Error.Write("middle"); ',
|
|
|
|
|
'[Console]::Error.Write("foo`n`nbar`n`nbaz")'
|
2017-09-29 16:28:15 -07:00
|
|
|
))
|
|
|
|
|
|
|
|
|
|
$out = & $powershell -noprofile -command $command 2>&1
|
|
|
|
|
|
|
|
|
|
# this check should be the first one, because $error is a global shared variable
|
|
|
|
|
It 'should not add records to $error variable' {
|
2020-08-07 14:19:17 -07:00
|
|
|
$error.Count | Should -Be 0
|
2017-09-29 16:28:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'uses ErrorRecord object to return stderr output' {
|
2018-12-28 08:48:23 +00:00
|
|
|
($out | Measure-Object).Count | Should -BeGreaterThan 1
|
2017-09-29 16:28:15 -07:00
|
|
|
|
2020-01-24 19:00:37 +00:00
|
|
|
$out[0] | Should -BeOfType System.Management.Automation.ErrorRecord
|
2018-03-21 10:47:08 -07:00
|
|
|
$out[0].FullyQualifiedErrorId | Should -Be 'NativeCommandError'
|
2017-09-29 16:28:15 -07:00
|
|
|
|
|
|
|
|
$out | Select-Object -Skip 1 | ForEach-Object {
|
2020-01-24 19:00:37 +00:00
|
|
|
$_ | Should -BeOfType System.Management.Automation.ErrorRecord
|
2018-03-21 10:47:08 -07:00
|
|
|
$_.FullyQualifiedErrorId | Should -Be 'NativeCommandErrorMessage'
|
2017-09-29 16:28:15 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'uses correct exception messages for error stream' {
|
2018-12-28 08:48:23 +00:00
|
|
|
($out | Measure-Object).Count | Should -Be 9
|
2018-03-21 10:47:08 -07:00
|
|
|
$out[0].Exception.Message | Should -BeExactly 'foo'
|
|
|
|
|
$out[1].Exception.Message | Should -BeExactly ''
|
|
|
|
|
$out[2].Exception.Message | Should -BeExactly 'bar'
|
|
|
|
|
$out[3].Exception.Message | Should -BeExactly ''
|
|
|
|
|
$out[4].Exception.Message | Should -BeExactly 'bazmiddlefoo'
|
|
|
|
|
$out[5].Exception.Message | Should -BeExactly ''
|
|
|
|
|
$out[6].Exception.Message | Should -BeExactly 'bar'
|
|
|
|
|
$out[7].Exception.Message | Should -BeExactly ''
|
|
|
|
|
$out[8].Exception.Message | Should -BeExactly 'baz'
|
2017-09-29 16:28:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'preserves error stream as is with Out-String' {
|
2018-03-21 10:47:08 -07:00
|
|
|
($out | Out-String).Replace("`r", '') | Should -BeExactly "foo`n`nbar`n`nbazmiddlefoo`n`nbar`n`nbaz`n"
|
2017-09-29 16:28:15 -07:00
|
|
|
}
|
2017-10-31 00:54:44 +08:00
|
|
|
|
2023-01-31 12:06:29 -08:00
|
|
|
It 'Does not get truncated or split when redirected' {
|
|
|
|
|
if (Test-IsWindowsArm64) {
|
|
|
|
|
Set-ItResult -Pending -Because "IOException: The handle is invalid."
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-31 00:54:44 +08:00
|
|
|
$longtext = "0123456789"
|
|
|
|
|
while ($longtext.Length -lt [console]::WindowWidth) {
|
|
|
|
|
$longtext += $longtext
|
|
|
|
|
}
|
2020-01-05 12:17:41 +05:00
|
|
|
& $powershell -c "& { [Console]::Error.WriteLine('$longtext') }" 2>&1 > $testdrive\error.txt
|
2017-10-31 00:54:44 +08:00
|
|
|
$e = Get-Content -Path $testdrive\error.txt
|
2018-03-21 10:47:08 -07:00
|
|
|
$e.Count | Should -Be 1
|
|
|
|
|
$e | Should -BeExactly $longtext
|
2017-10-31 00:54:44 +08:00
|
|
|
}
|
2017-09-29 16:28:15 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Describe 'piping powershell objects to finished native executable' -Tags 'CI' {
|
|
|
|
|
It 'doesn''t throw any exceptions, when we are piping to the closed executable' {
|
|
|
|
|
1..3 | ForEach-Object {
|
|
|
|
|
Start-Sleep -Milliseconds 100
|
2017-10-31 00:54:44 +08:00
|
|
|
# yield some multi-line formatted object
|
2017-09-29 16:28:15 -07:00
|
|
|
@{'a' = 'b'}
|
2018-03-21 10:47:08 -07:00
|
|
|
} | testexe -echoargs | Should -BeNullOrEmpty
|
2017-09-29 16:28:15 -07:00
|
|
|
}
|
|
|
|
|
}
|