MegaBites-AI/Windows-powershell
0372
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3using namespace System.Diagnostics4using namespace System.Management.Automation.Internal5 6Describe "PowerShell Command Debugging" -tags "CI" {7 8 BeforeAll {9 $powershell = Join-Path -Path $PSHOME -ChildPath "pwsh"10 }11 12 function NewProcessStartInfo([string]$CommandLine, [switch]$RedirectStdIn)13 {14 return [ProcessStartInfo]@{15 FileName = $powershell16 Arguments = $CommandLine17 RedirectStandardInput = $RedirectStdIn18 RedirectStandardOutput = $true19 RedirectStandardError = $true20 UseShellExecute = $false21 }22 }23 24 function RunPowerShell([ProcessStartInfo]$debugfn)25 {26 $process = [Process]::Start($debugfn)27 return $process28 }29 30 function EnsureChildHasExited([Process]$process, [int]$WaitTimeInMS = 15000)31 {32 $process.WaitForExit($WaitTimeInMS)33 34 if (!$process.HasExited)35 {36 $process.HasExited | Should -BeTrue37 $process.Kill()38 }39 }40 41 It "Should be able to step into debugging" {42 $debugfn = NewProcessStartInfo "-noprofile -c ""`$function:foo = { 'bar' }""" -RedirectStdIn43 $process = RunPowerShell $debugfn44 $process.StandardInput.Write("Set-PsBreakpoint -command foo`n")45 46 $process.StandardInput.Write("foo`n")47 48 $process.StandardInput.Write("s`n")49 50 $process.StandardInput.Write("s`n")51 52 $process.StandardInput.Write("s`n")53 54 $process.StandardInput.Close()55 56 EnsureChildHasExited $process57 $process.ExitCode | Should -Be 058 }59 60 It "Should be able to continue into debugging" {61 $debugfn = NewProcessStartInfo "-noprofile -c ""`$function:foo = { 'bar' }""" -RedirectStdIn62 $process = RunPowerShell $debugfn63 $process.StandardInput.Write("Set-PsBreakpoint -command foo`n")64 65 $process.StandardInput.Write("foo`n")66 67 $process.StandardInput.Write("c`n")68 $process.StandardOutput.ReadLine()69 $process.StandardOutput.ReadLine()70 71 $process.StandardInput.Close()72 73 EnsureChildHasExited $process74 $process.ExitCode | Should -Be 075 }76 77 It -Pending "Should be able to list help for debugging" {78 $debugfn = NewProcessStartInfo "-noprofile -c ""`$function:foo = { 'bar' }""" -RedirectStdIn79 $process = RunPowerShell $debugfn80 $process.StandardInput.Write("Set-PsBreakpoint -command foo`n")81 82 $process.StandardInput.Write("foo`n")83 84 $process.StandardInput.Write("h`n")85 86 foreach ($i in 1..38) {87 $line = $process.StandardOutput.ReadLine()88 }89 90 $process.StandardInput.Write("s`n")91 $process.StandardInput.Write("s`n")92 $process.StandardInput.Write("s`n")93 $process.StandardInput.Close()94 95 EnsureChildHasExited $process96 $line | Should -BeExactly "For instructions about how to customize your debugger prompt, type `"help about_prompt`"."97 }98 99 It "Should be able to step over debugging" {100 $debugfn = NewProcessStartInfo "-noprofile -c ""`$function:foo = { 'bar' }""" -RedirectStdIn101 $process = RunPowerShell $debugfn102 $process.StandardInput.Write("Set-PsBreakpoint -command foo`n")103 104 $process.StandardInput.Write("foo`n")105 $process.StandardInput.Write("v`n")106 $process.StandardInput.Write("v`n")107 $process.StandardInput.Write("v`n")108 109 $process.StandardInput.Close()110 111 EnsureChildHasExited $process112 $process.ExitCode | Should -Be 0113 }114 115 It "Should be able to step out of debugging" {116 $debugfn = NewProcessStartInfo "-noprofile -c ""`$function:foo = { 'bar' }""" -RedirectStdIn117 $process = RunPowerShell $debugfn118 $process.StandardInput.Write("Set-PsBreakpoint -command foo`n")119 120 $process.StandardInput.Write("foo`n")121 $process.StandardInput.Write("o`n")122 123 $process.StandardInput.Close()124 125 EnsureChildHasExited $process126 $process.ExitCode | Should -Be 0127 }128 129 It "Should be able to quit debugging" {130 $debugfn = NewProcessStartInfo "-noprofile -c ""`$function:foo = { 'bar' }""" -RedirectStdIn131 $process = RunPowerShell $debugfn132 $process.StandardInput.Write("Set-PsBreakpoint -command foo`n")133 134 $process.StandardInput.Write("foo`n")135 $process.StandardInput.Write("q`n")136 137 $process.StandardInput.Close()138 139 EnsureChildHasExited $process140 $process.ExitCode | Should -Be 0141 }142 143 It -Pending "Should be able to list source code in debugging" {144 $debugfn = NewProcessStartInfo "-noprofile -c ""`$function:foo = { 'bar' }""" -RedirectStdIn145 $process = RunPowerShell $debugfn146 $process.StandardInput.Write("Set-PsBreakpoint -command foo`n") | Write-Host147 148 $process.StandardInput.Write("foo`n") | Write-Host149 $process.StandardInput.Write("l`n") | Write-Host150 151 foreach ($i in 1..19) {152 $line = $process.StandardOutput.ReadLine()153 }154 155 $process.StandardInput.Write("`n")156 $process.StandardInput.Write("`n")157 $process.StandardInput.Write("`n")158 159 $line | Should -BeExactly " 1:* `$function:foo = { 'bar' }"160 $process.StandardInput.Close()161 EnsureChildHasExited $process162 163 }164 165 It -Pending "Should be able to get the call stack in debugging" {166 $debugfn = NewProcessStartInfo "-noprofile -c ""`$function:foo = { 'bar' }""" -RedirectStdIn167 $process = RunPowerShell $debugfn168 $process.StandardInput.Write("Set-PsBreakpoint -command foo`n") | Write-Host169 170 $process.StandardInput.Write("foo`n") | Write-Host171 $process.StandardInput.Write("k`n") | Write-Host172 173 foreach ($i in 1..20) {174 $line = $process.StandardOutput.ReadLine()175 }176 177 $line | Should -BeExactly "foo {} <No file>"178 $process.StandardInput.Close()179 EnsureChildHasExited $process180 181 }182 183}184 185# Scripting\Debugging\RunspaceDebuggingTests.cs186Describe "Runspace Debugging API tests" -Tag CI {187 Context "PSStandaloneMonitorRunspaceInfo tests" {188 BeforeAll {189 $runspace = [runspacefactory]::CreateRunspace()190 $runspaceType = [PSMonitorRunspaceType]::InvokeCommand191 $monitorInfo = [PSStandaloneMonitorRunspaceInfo]::new($runspace)192 $instanceId = $runspace.InstanceId193 $parentDebuggerId = [guid]::newguid()194 $ps = [powershell]::Create()195 $embeddedRunspaceInfo = [PSEmbeddedMonitorRunspaceInfo]::New($runspace,$runspaceType,$ps, $parentDebuggerId)196 }197 AfterAll {198 $runspace.Dispose()199 $ps.dispose()200 }201 202 It "PSStandaloneMonitorRunspaceInfo should throw when called with a null argument to the constructor" {203 { [PSStandaloneMonitorRunspaceInfo]::new($null) } |204 Should -Throw -ErrorId 'PSArgumentNullException'205 }206 207 It "PSStandaloneMonitorRunspaceInfo properties should have proper values" {208 $monitorInfo.Runspace.InstanceId | Should -Be $InstanceId209 $monitorInfo.RunspaceType | Should -BeExactly "Standalone"210 $monitorInfo.NestedDebugger | Should -BeNullOrEmpty211 }212 213 It "Embedded runspace properties should have proper values" {214 $embeddedRunspaceInfo.Runspace.InstanceId | Should -Be $InstanceId215 $embeddedRunspaceInfo.ParentDebuggerId | Should -Be $parentDebuggerId216 $embeddedRunspaceInfo.Command.InstanceId | Should -Be $ps.InstanceId217 $embeddedRunspaceInfo.NestedDebugger | Should -BeNullOrEmpty218 }219 }220 Context "Test Monitor RunspaceInfo API tests" {221 BeforeAll {222 $runspace = [runspacefactory]::CreateRunspace()223 $runspace.Open()224 $associationId = [guid]::newguid()225 $runspaceInfo = [PSStandaloneMonitorRunspaceInfo]::new($runspace)226 }227 AfterAll {228 $runspace.Dispose()229 }230 231 It "DebuggerUtils StartMonitoringRunspace requires non-null debugger" {232 { [DebuggerUtils]::StartMonitoringRunspace($null,$runspaceInfo) } |233 Should -Throw -ErrorId 'PSArgumentNullException'234 }235 It "DebuggerUtils StartMonitoringRunspace requires non-null runspaceInfo" {236 { [DebuggerUtils]::StartMonitoringRunspace($runspace.Debugger,$null) } |237 Should -Throw -ErrorId 'PSArgumentNullException'238 }239 240 It "DebuggerUtils EndMonitoringRunspace requires non-null debugger" {241 { [DebuggerUtils]::EndMonitoringRunspace($null,$runspaceInfo) } |242 Should -Throw -ErrorId 'PSArgumentNullException'243 }244 It "DebuggerUtils EndMonitoringRunspace requires non-null runspaceInfo" {245 { [DebuggerUtils]::EndMonitoringRunspace($runspace.Debugger,$null) } |246 Should -Throw -ErrorId 'PSArgumentNullException'247 }248 249 }250}251 252 