"Fossies" - the Fresh Open Source Software Archive

Member "PowerShell-7.2.6/test/powershell/Language/Scripting/ActionPreference.Tests.ps1" (11 Aug 2022, 18241 Bytes) of package /linux/misc/PowerShell-7.2.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Microsoft PowerShell source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 # Copyright (c) Microsoft Corporation.
    2 # Licensed under the MIT License.
    3 
    4 Describe "Tests for (error, warning, etc) action preference" -Tags "CI" {
    5     $commonActionPreferenceParameterTestCases = foreach ($commonParameterName in [System.Management.Automation.Cmdlet]::CommonParameters | Select-String Action) {
    6         @{
    7             ActionPreferenceParameterName = $commonParameterName
    8         }
    9     }
   10 
   11     $actionPreferenceVariableTestCases = foreach ($variable in Get-Variable -Name *Preference -Scope Global | Where-Object Value -Is [System.Management.Automation.ActionPreference]) {
   12         @{
   13             ActionPreferenceVariableName = $variable.Name
   14             StreamName = $variable.Name -replace '(Action)?Preference$'
   15         }
   16     }
   17 
   18     $actionPreferenceVariableValueTestCases = @(
   19         @{
   20             Value = [System.Management.Automation.ActionPreference]::Suspend
   21             DisplayValue = '[System.Management.Automation.ActionPreference]::Suspend'
   22         }
   23         @{
   24             Value        = 'Suspend'
   25             DisplayValue = '''Suspend'''
   26         }
   27     )
   28 
   29     BeforeAll {
   30         $orgin = $GLOBAL:errorActionPreference
   31 
   32         function Join-TestCase {
   33             [OutputType([Hashtable[]])]
   34             [CmdletBinding()]
   35             param(
   36                 [Hashtable[]]$Set1,
   37                 [Hashtable[]]$Set2
   38             )
   39             foreach ($ht1 in $Set1) {
   40                 foreach ($ht2 in $Set2) {
   41                     $ht1 + $ht2
   42                 }
   43             }
   44         }
   45 
   46         function Test-ActionPreferenceVariableSuspendValue {
   47             [CmdletBinding()]
   48             param(
   49                 $Value
   50             )
   51             if ($DebugPreference -eq $Value) {
   52                 Write-Debug -Message 'A debug message'
   53             } elseif ($ErrorActionPreference -eq $Value) {
   54                 Write-Error -Message 'An error message'
   55             } elseif ($InformationPreference -eq $Value) {
   56                 Write-Information -MessageData 'Some information'
   57             } elseif ($ProgressPreference -eq $Value) {
   58                 Write-Progress -Activity 'Some progress'
   59             } elseif ($VerbosePreference -eq $Value) {
   60                 Write-Verbose -Message 'A verbose message'
   61             } elseif ($WarningPreference -eq $Value) {
   62                 Write-Warning -Message 'A warning message'
   63             }
   64         }
   65     }
   66 
   67     AfterAll {
   68         if ($GLOBAL:errorActionPreference -ne $orgin) {
   69             $GLOBAL:errorActionPreference = $orgin
   70         }
   71     }
   72 
   73     Context 'Setting ErrorActionPreference to stop prevents user from getting the error exception' {
   74         $err = $null
   75         try {
   76             Get-ChildItem nosuchfile.nosuchextension -ErrorAction stop -ErrorVariable err
   77         } catch { }
   78 
   79         It '$err.Count' { $err.Count | Should -Be 1 }
   80         It '$err[0] should not be $null' { $err[0] | Should -Not -BeNullOrEmpty }
   81         It '$err[0].GetType().Name' { $err[0] | Should -BeOfType System.Management.Automation.ActionPreferenceStopException }
   82         It '$err[0].ErrorRecord' { $err[0].ErrorRecord | Should -Not -BeNullOrEmpty }
   83         It '$err[0].ErrorRecord.Exception.GetType().Name' { $err[0].ErrorRecord.Exception | Should -BeOfType System.Management.Automation.ItemNotFoundException }
   84     }
   85 
   86     It 'Action preference of Ignore can be set as a preference variable using a string value' {
   87         try {
   88             Remove-Variable -Name ErrorActionPreference -Scope Global -Force
   89             $GLOBAL:ErrorActionPreference = 'Ignore'
   90             $errorCount = $error.Count
   91             Get-Process -Name asdfasdfasdf
   92             $error.Count | Should -BeExactly $errorCount
   93         } finally {
   94             Remove-Variable -Name ErrorActionPreference -Scope Global
   95             # Re-create the action preference variable as a strongly typed variable like it was before
   96             [System.Management.Automation.ActionPreference]$GLOBAL:ErrorActionPreference = $orgin
   97         }
   98     }
   99 
  100     It 'Action preference of Ignore can be set as a preference variable using an enumerated value' {
  101         try {
  102             $GLOBAL:ErrorActionPreference = [System.Management.Automation.ActionPreference]::Ignore
  103             $errorCount = $error.Count
  104             Get-Process -Name asdfasdfasdf
  105             $error.Count | Should -BeExactly $errorCount
  106         } finally {
  107             $GLOBAL:ErrorActionPreference = $orgin
  108         }
  109     }
  110 
  111     It 'The $global:<ActionPreferenceVariableName> variable does not support Suspend' -TestCases $actionPreferenceVariableTestCases {
  112         param($ActionPreferenceVariableName)
  113 
  114         $e = {
  115             Set-Variable -Name $ActionPreferenceVariableName -Scope Global -Value ([System.Management.Automation.ActionPreference]::Suspend)
  116         } | Should -Throw -ErrorId RuntimeException -PassThru
  117 
  118         $e.CategoryInfo.Reason | Should -BeExactly 'ArgumentTransformationMetadataException'
  119     }
  120 
  121     It 'A local $<ActionPreferenceVariableName> variable does not support <DisplayValue>' -TestCases (Join-TestCase -Set1 $actionPreferenceVariableTestCases -Set2 $actionPreferenceVariableValueTestCases) {
  122         param(
  123             $ActionPreferenceVariableName,
  124             $StreamName,
  125             $Value,
  126             $DisplayValue
  127         )
  128 
  129         $e = {
  130             Set-Variable -Name $ActionPreferenceVariableName -Value $Value
  131             Test-ActionPreferenceVariableSuspendValue -Value $Value
  132         } | Should -Throw -ErrorId "System.NotSupportedException$(if ($StreamName -ne 'Error') {",Microsoft.PowerShell.Commands.Write${StreamName}Command"})" -PassThru
  133 
  134         $e.CategoryInfo.Reason | Should -BeExactly 'NotSupportedException'
  135     }
  136 
  137     It 'enum disambiguation works' {
  138         $errorCount = $error.Count
  139         Get-Process -Name asdfasdfsadfsadf -ErrorAction Ig
  140 
  141         $error.Count | Should -BeExactly $errorCount
  142     }
  143 
  144     #issue 2076
  145     It 'The -<ActionPreferenceParameterName> common parameter does not support Suspend on cmdlets' -TestCases $commonActionPreferenceParameterTestCases {
  146         param($ActionPreferenceParameterName)
  147 
  148         $commonParameters = @{
  149             "${ActionPreferenceParameterName}" = [System.Management.Automation.ActionPreference]::Suspend
  150         }
  151 
  152         { Write-Output -InputObject Test @commonParameters } | Should -Throw -ErrorId "ParameterBindingFailed,Microsoft.PowerShell.Commands.WriteOutputCommand"
  153     }
  154 
  155     It 'The -<ActionPreferenceParameterName> common parameter does not support Suspend on functions' -TestCases $commonActionPreferenceParameterTestCases {
  156         param($ActionPreferenceParameterName)
  157 
  158         function MyHelperFunction {
  159             [CmdletBinding()]
  160             param()
  161             "Hello"
  162         }
  163 
  164         $commonParameters = @{
  165             "${ActionPreferenceParameterName}" = [System.Management.Automation.ActionPreference]::Suspend
  166         }
  167 
  168         { MyHelperFunction -ErrorAction Suspend } | Should -Throw -ErrorId "ParameterBindingFailed,MyHelperFunction"
  169     }
  170 
  171     It '<switch> does not take precedence over $ErrorActionPreference' -TestCases @(
  172         @{switch = "Verbose" },
  173         @{switch = "Debug" }
  174     ) {
  175         param($switch)
  176         $ErrorActionPreference = "SilentlyContinue"
  177         $params = @{
  178             ItemType = "File";
  179             Path     = "$testdrive\test.txt";
  180             Confirm  = $false
  181         }
  182         New-Item @params > $null
  183         $params += @{$switch = $true }
  184         { New-Item @params } | Should -Not -Throw
  185         $ErrorActionPreference = "Stop"
  186         { New-Item @params } | Should -Throw -ErrorId "NewItemIOError,Microsoft.PowerShell.Commands.NewItemCommand"
  187         Remove-Item "$testdrive\test.txt" -Force
  188     }
  189 
  190     It "Parameter binding '-<name>' throws correctly (no NRE) if argument is <argValue>" -TestCases @(
  191         @{ name = "ErrorAction";       argValue = "null";           arguments = @{ ErrorAction = $null } }
  192         @{ name = "WarningAction";     argValue = "null";           arguments = @{ WarningAction = $null } }
  193         @{ name = "InformationAction"; argValue = "null";           arguments = @{ InformationAction = $null } }
  194         @{ name = "ErrorAction";       argValue = "AutomationNull"; arguments = @{ ErrorAction = [System.Management.Automation.Internal.AutomationNull]::Value } }
  195         @{ name = "WarningAction";     argValue = "AutomationNull"; arguments = @{ WarningAction = [System.Management.Automation.Internal.AutomationNull]::Value } }
  196         @{ name = "InformationAction"; argValue = "AutomationNull"; arguments = @{ InformationAction = [System.Management.Automation.Internal.AutomationNull]::Value } }
  197     ) {
  198         param($arguments)
  199 
  200         $err = $null
  201         try {
  202             Test-Path .\noexistfile.ps1 @arguments
  203         } catch {
  204             $err = $_
  205         }
  206 
  207         $err.FullyQualifiedErrorId | Should -BeExactly "ParameterBindingFailed,Microsoft.PowerShell.Commands.TestPathCommand"
  208         $err.Exception.InnerException.InnerException | Should -BeOfType "System.Management.Automation.PSInvalidCastException"
  209     }
  210 }
  211 
  212 Describe 'ActionPreference.Break tests' -Tag 'CI' {
  213 
  214     BeforeAll {
  215         Register-DebuggerHandler
  216     }
  217 
  218     AfterAll {
  219         Unregister-DebuggerHandler
  220     }
  221 
  222     Context '-ErrorAction Break should break on a non-terminating error' {
  223         BeforeAll {
  224             $testScript = {
  225                 function Test-Break {
  226                     [CmdletBinding()]
  227                     param()
  228                     try {
  229                         # Generate a non-terminating error
  230                         Write-Error 'This is a non-terminating error.'
  231                         # Do something afterwards
  232                         'This should still run'
  233                     } catch {
  234                         'Do nothing'
  235                     } finally {
  236                         'This finally runs'
  237                     }
  238                 }
  239                 Test-Break -ErrorAction Break
  240             }
  241 
  242             $results = @(Test-Debugger -Scriptblock $testScript -CommandQueue 'v', 'v')
  243         }
  244 
  245         It 'Should show 3 debugger commands were invoked' {
  246             # There is always an implicit 'c' command that keeps the debugger automation moving
  247             $results.Count | Should -Be 3
  248         }
  249 
  250         It 'The breakpoint should be the statement that generated the non-terminating error' {
  251             $results[0] | ShouldHaveExtent -Line 7 -FromColumn 25 -ToColumn 71
  252         }
  253 
  254         It 'The second statement should be the statement after that which generated the non-terminating error' {
  255             $results[1] | ShouldHaveExtent -Line 9 -FromColumn 25 -ToColumn 48
  256         }
  257 
  258         It 'The third statement should be the statement in the finally block' {
  259             $results[2] | ShouldHaveExtent -Line 13 -FromColumn 25 -ToColumn 44
  260         }
  261     }
  262 
  263     Context '-ErrorAction Break should break on a terminating error' {
  264         BeforeAll {
  265             $testScript = {
  266                 function Test-Break {
  267                     [CmdletBinding()]
  268                     param()
  269                     try {
  270                         # Generate a terminating error
  271                         Get-Process -TheAnswer 42
  272                         # Do something afterwards
  273                         'This should not run'
  274                     } catch {
  275                         'Do nothing'
  276                     } finally {
  277                         'This finally runs'
  278                     }
  279                 }
  280                 Test-Break -ErrorAction Break
  281             }
  282 
  283             $results = @(Test-Debugger -Scriptblock $testScript -CommandQueue 'v', 'v')
  284         }
  285 
  286         It 'Should show 3 debugger commands were invoked' {
  287             # There is always an implicit 'c' command that keeps the debugger automation moving
  288             $results.Count | Should -Be 3
  289         }
  290 
  291         It 'The breakpoint should be the statement that generated the terminating error' {
  292             $results[0] | ShouldHaveExtent -Line 7 -FromColumn 25 -ToColumn 50
  293         }
  294 
  295         It 'The second statement should be the statement in the catch block where the terminating error is caught' {
  296             $results[1] | ShouldHaveExtent -Line 11 -FromColumn 25 -ToColumn 37
  297         }
  298 
  299         It 'The third statement should be the statement in the finally block' {
  300             $results[2] | ShouldHaveExtent -Line 13 -FromColumn 25 -ToColumn 44
  301         }
  302     }
  303 
  304     Context '-ErrorAction Break should not break on a naked rethrow' {
  305         BeforeAll {
  306             $testScript = {
  307                 function Test-Break {
  308                     [CmdletBinding()]
  309                     param()
  310                     try {
  311                         try {
  312                             # Generate a terminating error
  313                             Get-Process -TheAnswer 42
  314                         } catch {
  315                             throw
  316                         }
  317                     } catch {
  318                         # Swallow the exception here
  319                     }
  320                 }
  321                 Test-Break -ErrorAction Break
  322             }
  323 
  324             $results = @(Test-Debugger -Scriptblock $testScript)
  325         }
  326 
  327         It 'Should show 1 debugger command was invoked' {
  328             # ErrorAction break should only trigger on the initial terminating error
  329             $results.Count | Should -Be 1
  330         }
  331 
  332         It 'The breakpoint should be the statement that generated the terminating error' {
  333             $results[0] | ShouldHaveExtent -Line 8 -FromColumn 29 -ToColumn 54
  334         }
  335     }
  336 
  337     Context '-ErrorAction Break should break when throwing a specific error or object' {
  338         BeforeAll {
  339             $testScript = {
  340                 function Test-Break {
  341                     [CmdletBinding()]
  342                     param()
  343                     try {
  344                         try {
  345                             # Generate a terminating error
  346                             Get-Process -TheAnswer 42
  347                         } catch {
  348                             throw $_
  349                         }
  350                     } catch {
  351                         # Swallow the exception here
  352                     }
  353                 }
  354                 Test-Break -ErrorAction Break
  355             }
  356 
  357             $results = @(Test-Debugger -Scriptblock $testScript)
  358         }
  359 
  360         It 'Should show 2 debugger commands were invoked' {
  361             # ErrorAction break should trigger on the initial terminating error and the throw
  362             # since it throws a "new" error (throwing anything is considered a new terminating
  363             # error)
  364             $results.Count | Should -Be 2
  365         }
  366 
  367         It 'The first breakpoint should be the statement that generated the terminating error' {
  368             $results[0] | ShouldHaveExtent -Line 8 -FromColumn 29 -ToColumn 54
  369         }
  370 
  371         It 'The second breakpoint should be the statement that threw $_' {
  372             $results[1] | ShouldHaveExtent -Line 10 -FromColumn 29 -ToColumn 37
  373         }
  374     }
  375 
  376     Context 'Other message types should break on their corresponding messages when requested' {
  377         BeforeAll {
  378             $testScript = {
  379                 function Test-Break {
  380                     [CmdletBinding()]
  381                     param()
  382                     Write-Warning -Message 'This is a warning message'
  383                     Write-Verbose -Message 'This is a verbose message'
  384                     Write-Debug -Message 'This is a debug message'
  385                     Write-Information -MessageData 'This is an information message'
  386                     Write-Progress -Activity 'This shows progress'
  387                 }
  388                 Test-Break -WarningAction Break -InformationAction Break *>$null
  389                 $WarningPreference = $VerbosePreference = $DebugPreference = $InformationPreference = $ProgressPreference = [System.Management.Automation.ActionPreference]::Break
  390                 Test-Break *>$null
  391             }
  392 
  393             $results = @(Test-Debugger -Scriptblock $testScript)
  394         }
  395 
  396         It 'Should show 7 debugger commands were invoked' {
  397             # When no debugger commands are provided, 'c' is invoked every time a breakpoint is hit
  398             $results.Count | Should -Be 7
  399         }
  400 
  401         It 'Write-Warning should trigger a breakpoint from -WarningAction Break' {
  402             $results[0] | ShouldHaveExtent -Line 5 -FromColumn 21 -ToColumn 71
  403         }
  404 
  405         It 'Write-Information should trigger a breakpoint from -InformationAction Break' {
  406             $results[1] | ShouldHaveExtent -Line 8 -FromColumn 21 -ToColumn 84
  407         }
  408 
  409         It 'Write-Warning should trigger a breakpoint from $WarningPreference = [System.Management.Automation.ActionPreference]::Break' {
  410             $results[2] | ShouldHaveExtent -Line 5 -FromColumn 21 -ToColumn 71
  411         }
  412 
  413         It 'Write-Verbose should trigger a breakpoint from $VerbosePreference = [System.Management.Automation.ActionPreference]::Break' {
  414             $results[3] | ShouldHaveExtent -Line 6 -FromColumn 21 -ToColumn 71
  415         }
  416 
  417         It 'Write-Debug should trigger a breakpoint from $DebugPreference = [System.Management.Automation.ActionPreference]::Break' {
  418             $results[4] | ShouldHaveExtent -Line 7 -FromColumn 21 -ToColumn 67
  419         }
  420 
  421         It 'Write-Information should trigger a breakpoint from $InformationPreference = [System.Management.Automation.ActionPreference]::Break' {
  422             $results[5] | ShouldHaveExtent -Line 8 -FromColumn 21 -ToColumn 84
  423         }
  424 
  425         It 'Write-Progress should trigger a breakpoint from $ProgressPreference = [System.Management.Automation.ActionPreference]::Break' {
  426             $results[6] | ShouldHaveExtent -Line 9 -FromColumn 21 -ToColumn 67
  427         }
  428     }
  429 
  430     Context 'ActionPreference.Break in jobs' {
  431 
  432         BeforeAll {
  433             $job = Start-Job {
  434                 $ErrorActionPreference = [System.Management.Automation.ActionPreference]::Break
  435                 Get-Process -TheAnswer 42
  436             }
  437         }
  438 
  439         AfterAll {
  440             Remove-Job -Job $job -Force
  441         }
  442 
  443         It 'ActionPreference.Break should break in a running job' {
  444             Wait-UntilTrue -sb { $job.State -eq 'AtBreakpoint' } -TimeoutInMilliseconds (60 * 1000) -IntervalInMilliseconds 100 | Should -BeTrue
  445         }
  446     }
  447 }