public async Task DebuggerVariableHashtableDisplaysCorrectly() { await this.debugService.SetLineBreakpoints( this.variableScriptFile, new[] { BreakpointDetails.Create("", 18) }); // Execute the script and wait for the breakpoint to be hit Task executeTask = this.powerShellContext.ExecuteScriptString( this.variableScriptFile.FilePath); await this.AssertDebuggerStopped(this.variableScriptFile.FilePath); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); var var = variables.FirstOrDefault(v => v.Name == "$assocArrVar"); Assert.NotNull(var); Assert.Equal("[Hashtable: 2]", var.ValueString); Assert.True(var.IsExpandable); var childVars = debugService.GetVariables(var.Id); Assert.Equal(9, childVars.Length); Assert.Equal("[0]", childVars[0].Name); Assert.Equal("[secondChild, 42]", childVars[0].ValueString); Assert.Equal("[1]", childVars[1].Name); Assert.Equal("[firstChild, \"Child\"]", childVars[1].ValueString); // Abort execution of the script this.powerShellContext.AbortExecution(); }
public async Task DebuggerStopsOnLineBreakpoints() { BreakpointDetails[] breakpoints = await this.debugService.SetLineBreakpoints( this.debugScriptFile, new[] { BreakpointDetails.Create("", 5), BreakpointDetails.Create("", 7) }); await this.AssertStateChange(PowerShellContextState.Ready); Task executeTask = this.powerShellContext.ExecuteScriptWithArgs( this.debugScriptFile.FilePath); // Wait for a couple breakpoints await this.AssertDebuggerStopped(this.debugScriptFile.FilePath, 5); this.debugService.Continue(); await this.AssertDebuggerStopped(this.debugScriptFile.FilePath, 7); // Abort script execution early and wait for completion this.debugService.Abort(); await executeTask; }
public async Task DebuggerStopsOnHitConditionBreakpoint() { const int hitCount = 5; BreakpointDetails[] breakpoints = await this.debugService.SetLineBreakpoints( this.debugScriptFile, new[] { BreakpointDetails.Create("", 6, null, null, $"{hitCount}"), }); await this.AssertStateChange(PowerShellContextState.Ready); Task executeTask = this.powerShellContext.ExecuteScriptWithArgs( this.debugScriptFile.FilePath); // Wait for conditional breakpoint to hit await this.AssertDebuggerStopped(this.debugScriptFile.FilePath, 6); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); // Verify the breakpoint only broke at the condition ie. $i -eq breakpointValue1 var i = variables.FirstOrDefault(v => v.Name == "$i"); Assert.NotNull(i); Assert.False(i.IsExpandable); Assert.Equal($"{hitCount}", i.ValueString); // Abort script execution early and wait for completion this.debugService.Abort(); await executeTask; }
public async Task DebuggerVariablePSObjectDisplaysCorrectly() { await this.debugService.SetLineBreakpointsAsync( this.variableScriptFile, new[] { BreakpointDetails.Create("", 18) }); // Execute the script and wait for the breakpoint to be hit Task executeTask = this.powerShellContext.ExecuteScriptStringAsync( this.variableScriptFile.FilePath); await this.AssertDebuggerStopped(this.variableScriptFile.FilePath); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); var psObjVar = variables.FirstOrDefault(v => v.Name == "$psObjVar"); Assert.NotNull(psObjVar); Assert.True("@{Age=75; Name=John}".Equals(psObjVar.ValueString) || "@{Name=John; Age=75}".Equals(psObjVar.ValueString)); Assert.True(psObjVar.IsExpandable); IDictionary <string, string> childVars = debugService.GetVariables(psObjVar.Id).ToDictionary(v => v.Name, v => v.ValueString); Assert.Equal(2, childVars.Count); Assert.Contains("Age", childVars.Keys); Assert.Contains("Name", childVars.Keys); Assert.Equal("75", childVars["Age"]); Assert.Equal("\"John\"", childVars["Name"]); // Abort execution of the script this.powerShellContext.AbortExecution(); }
public async Task DebuggerVariablePSCustomObjectDisplaysCorrectly() { await this.debugService.SetLineBreakpoints( this.variableScriptFile, new[] { BreakpointDetails.Create("", 18) }); // Execute the script and wait for the breakpoint to be hit Task executeTask = this.powerShellContext.ExecuteScriptString( this.variableScriptFile.FilePath); await this.AssertDebuggerStopped(this.variableScriptFile.FilePath); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); var var = variables.FirstOrDefault(v => v.Name == "$psCustomObjVar"); Assert.NotNull(var); Assert.Equal("@{Name=Paul; Age=73}", var.ValueString); Assert.True(var.IsExpandable); var childVars = debugService.GetVariables(var.Id); Assert.Equal(2, childVars.Length); Assert.Equal("Name", childVars[0].Name); Assert.Equal("\"Paul\"", childVars[0].ValueString); Assert.Equal("Age", childVars[1].Name); Assert.Equal("73", childVars[1].ValueString); // Abort execution of the script this.powerShellContext.AbortExecution(); }
private async void DebugService_BreakpointUpdated(object sender, BreakpointUpdatedEventArgs e) { string reason = "changed"; if (this.setBreakpointInProgress) { // Don't send breakpoint update notifications when setting // breakpoints on behalf of the client. return; } switch (e.UpdateType) { case BreakpointUpdateType.Set: reason = "new"; break; case BreakpointUpdateType.Removed: reason = "removed"; break; } var breakpoint = Protocol.DebugAdapter.Breakpoint.Create( BreakpointDetails.Create(e.Breakpoint)); breakpoint.Verified = e.UpdateType != BreakpointUpdateType.Disabled; await this.messageSender.SendEvent( BreakpointEvent.Type, new BreakpointEvent { Reason = reason, Breakpoint = breakpoint }); }
public async Task DebuggerVariableNullStringDisplaysCorrectly() { await this.debugService.SetLineBreakpointsAsync( this.variableScriptFile, new[] { BreakpointDetails.Create(this.variableScriptFile.FilePath, 16) }).ConfigureAwait(false); // Execute the script and wait for the breakpoint to be hit Task executeTask = this.powerShellContext.ExecuteScriptStringAsync( this.variableScriptFile.FilePath); await this.AssertDebuggerStopped(this.variableScriptFile.FilePath).ConfigureAwait(false); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); var nullStringVar = variables.FirstOrDefault(v => v.Name == "$nullString"); Assert.NotNull(nullStringVar); Assert.Equal("[NullString]", nullStringVar.ValueString); Assert.True(nullStringVar.IsExpandable); // Abort script execution early and wait for completion this.debugService.Abort(); await executeTask.ConfigureAwait(false); }
public async Task DebuggerVariableProcessObjDisplaysCorrectly() { await this.debugService.SetLineBreakpointsAsync( this.variableScriptFile, new[] { BreakpointDetails.Create(this.variableScriptFile.FilePath, 19) }).ConfigureAwait(false); // Execute the script and wait for the breakpoint to be hit Task executeTask = this.powerShellContext.ExecuteScriptStringAsync( this.variableScriptFile.FilePath); await this.AssertDebuggerStopped(this.variableScriptFile.FilePath).ConfigureAwait(false); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); var var = variables.FirstOrDefault(v => v.Name == "$procVar"); Assert.NotNull(var); Assert.StartsWith("System.Diagnostics.Process", var.ValueString); Assert.True(var.IsExpandable); var childVars = debugService.GetVariables(var.Id); Assert.Equal(53, childVars.Length); // Abort script execution early and wait for completion this.debugService.Abort(); await executeTask.ConfigureAwait(false); }
public async Task DebuggerStopsOnConditionalAndHitConditionBreakpoint() { const int hitCount = 5; await this.debugService.SetLineBreakpointsAsync( this.debugScriptFile, new[] { BreakpointDetails.Create(this.debugScriptFile.FilePath, 6, null, $"$i % 2 -eq 0", $"{hitCount}"), }).ConfigureAwait(false); Task executeTask = this.powerShellContext.ExecuteScriptWithArgsAsync( this.debugScriptFile.FilePath); // Wait for conditional breakpoint to hit await this.AssertDebuggerStopped(this.debugScriptFile.FilePath, 6).ConfigureAwait(false); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); // Verify the breakpoint only broke at the condition ie. $i -eq breakpointValue1 var i = variables.FirstOrDefault(v => v.Name == "$i"); Assert.NotNull(i); Assert.False(i.IsExpandable); // Condition is even numbers ($i starting at 1) should end up on 10 with a hit count of 5. Assert.Equal("10", i.ValueString); // Abort script execution early and wait for completion this.debugService.Abort(); await executeTask.ConfigureAwait(false); }
public Task Start(List <KeyValuePair <string, object> > inputParameters) { IsActiveDebugging = true; if (_cachedScriptPath == null) { CacheRunbook(); } var scriptFile = _editorSession.Workspace.GetFile(_cachedScriptPath); var breakpointDetails = _breakpoints.Select(breakpoint => BreakpointDetails.Create("", breakpoint.Line + 2)).ToArray(); // Set the breakpoints return(_editorSession.DebugService .SetLineBreakpoints(scriptFile, breakpointDetails) .ContinueWith( (t) => { // Debug the script _editorSession.PowerShellContext .ExecuteScriptAtPath(_cachedScriptPath) .ContinueWith( (t2) => { if (_cachedScriptPath != null) { File.Delete(_cachedScriptPath); _cachedScriptPath = null; } IsActiveDebugging = false; DebuggerFinished?.Invoke(this, new EventArgs()); }); })); }
public async Task DebuggerSetsAndClearsLineBreakpoints() { BreakpointDetails[] breakpoints = await this.debugService.SetLineBreakpoints( this.debugScriptFile, new[] { BreakpointDetails.Create("", 5), BreakpointDetails.Create("", 10) }); Assert.Equal(2, breakpoints.Length); Assert.Equal(5, breakpoints[0].LineNumber); Assert.Equal(10, breakpoints[1].LineNumber); breakpoints = await this.debugService.SetLineBreakpoints( this.debugScriptFile, new[] { BreakpointDetails.Create("", 2) }); Assert.Equal(1, breakpoints.Length); Assert.Equal(2, breakpoints[0].LineNumber); breakpoints = await this.debugService.SetLineBreakpoints( this.debugScriptFile, new[] { BreakpointDetails.Create("", 0) }); Assert.Equal(0, breakpoints.Length); }
public async Task DebuggerVariableEnumDisplaysCorrectly() { await this.debugService.SetLineBreakpoints( this.variableScriptFile, new[] { BreakpointDetails.Create("", 18) }); // Execute the script and wait for the breakpoint to be hit Task executeTask = this.powerShellContext.ExecuteScriptString( this.variableScriptFile.FilePath); await this.AssertDebuggerStopped(this.variableScriptFile.FilePath); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); var var = variables.FirstOrDefault(v => v.Name == "$enumVar"); Assert.NotNull(var); Assert.Equal("Continue", var.ValueString); Assert.False(var.IsExpandable); // Abort execution of the script this.powerShellContext.AbortExecution(); }
public async Task DebuggerProvidesMessageForInvalidConditionalBreakpoint() { BreakpointDetails[] breakpoints = await this.debugService.SetLineBreakpointsAsync( this.debugScriptFile, new[] { // TODO: Add this breakpoint back when it stops moving around?! The ordering // of these two breakpoints seems to do with which framework executes the // code. Best guess is that `IEnumerable` is not stably sorted so `ToArray` // returns different orderings. However, that doesn't explain why this is // the only affected test. // BreakpointDetails.Create(this.debugScriptFile.FilePath, 5), BreakpointDetails.Create(this.debugScriptFile.FilePath, 10, column: null, condition: "$i -ez 100") }).ConfigureAwait(false); Assert.Equal(1, breakpoints.Length); // Assert.Equal(5, breakpoints[0].LineNumber); // Assert.True(breakpoints[0].Verified); // Assert.Null(breakpoints[0].Message); Assert.Equal(10, breakpoints[0].LineNumber); Assert.False(breakpoints[0].Verified); Assert.NotNull(breakpoints[0].Message); Assert.Contains("Unexpected token '-ez'", breakpoints[0].Message); // Abort debugger this.debugService.Abort(); }
public async Task DebuggerAcceptsScriptArgs(string[] args) { // The path is intentionally odd (some escaped chars but not all) because we are testing // the internal path escaping mechanism - it should escape certains chars ([, ] and space) but // it should not escape already escaped chars. ScriptFile debugWithParamsFile = this.workspace.GetFile( @"..\..\..\..\PowerShellEditorServices.Test.Shared\Debugging\Debug` W&ith Params `[Test].ps1"); await this.debugService.SetLineBreakpoints( debugWithParamsFile, new[] { BreakpointDetails.Create("", 3) }); string arguments = string.Join(" ", args); // Execute the script and wait for the breakpoint to be hit Task executeTask = this.powerShellContext.ExecuteScriptWithArgs( debugWithParamsFile.FilePath, arguments); await this.AssertDebuggerStopped(debugWithParamsFile.FilePath); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); var var = variables.FirstOrDefault(v => v.Name == "$Param1"); Assert.NotNull(var); Assert.Equal("\"Foo\"", var.ValueString); Assert.False(var.IsExpandable); var = variables.FirstOrDefault(v => v.Name == "$Param2"); Assert.NotNull(var); Assert.True(var.IsExpandable); var childVars = debugService.GetVariables(var.Id); Assert.Equal(9, childVars.Length); Assert.Equal("\"Bar\"", childVars[0].ValueString); Assert.Equal("\"Baz\"", childVars[1].ValueString); var = variables.FirstOrDefault(v => v.Name == "$Force"); Assert.NotNull(var); Assert.Equal("True", var.ValueString); Assert.True(var.IsExpandable); var = variables.FirstOrDefault(v => v.Name == "$args"); Assert.NotNull(var); Assert.True(var.IsExpandable); childVars = debugService.GetVariables(var.Id); Assert.Equal(8, childVars.Length); Assert.Equal("\"Extra1\"", childVars[0].ValueString); // Abort execution of the script this.powerShellContext.AbortExecution(); }
public static Breakpoint Create( BreakpointDetails breakpointDetails) { return new Breakpoint { Line = breakpointDetails.LineNumber, Verified = true }; }
protected async Task HandleSetBreakpointsRequest( SetBreakpointsRequestArguments setBreakpointsParams, RequestContext <SetBreakpointsResponseBody> requestContext) { ScriptFile scriptFile; // Fix for issue #195 - user can change name of file outside of VSCode in which case // VSCode sends breakpoint requests with the original filename that doesn't exist anymore. try { scriptFile = editorSession.Workspace.GetFile(setBreakpointsParams.Source.Path); } catch (FileNotFoundException) { Logger.Write( LogLevel.Warning, $"Attempted to set breakpoints on a non-existing file: {setBreakpointsParams.Source.Path}"); var srcBreakpoints = setBreakpointsParams.Breakpoints .Select(srcBkpt => Protocol.DebugAdapter.Breakpoint.Create( srcBkpt, setBreakpointsParams.Source.Path, "Source does not exist, breakpoint not set.")); // Return non-verified breakpoint message. await requestContext.SendResult( new SetBreakpointsResponseBody { Breakpoints = srcBreakpoints.ToArray() }); return; } var breakpointDetails = new BreakpointDetails[setBreakpointsParams.Breakpoints.Length]; for (int i = 0; i < breakpointDetails.Length; i++) { SourceBreakpoint srcBreakpoint = setBreakpointsParams.Breakpoints[i]; breakpointDetails[i] = BreakpointDetails.Create( scriptFile.FilePath, srcBreakpoint.Line, srcBreakpoint.Column, srcBreakpoint.Condition); } BreakpointDetails[] breakpoints = await editorSession.DebugService.SetLineBreakpoints( scriptFile, breakpointDetails); await requestContext.SendResult( new SetBreakpointsResponseBody { Breakpoints = breakpoints .Select(Protocol.DebugAdapter.Breakpoint.Create) .ToArray() }); }
public static Breakpoint Create( BreakpointDetails breakpointDetails) { return(new Breakpoint { Line = breakpointDetails.LineNumber, Verified = true }); }
public async Task DebuggerGetsVariables() { await this.debugService.SetLineBreakpointsAsync( this.variableScriptFile, new[] { BreakpointDetails.Create(this.variableScriptFile.FilePath, 14) }).ConfigureAwait(false); // Execute the script and wait for the breakpoint to be hit Task executeTask = this.powerShellContext.ExecuteScriptStringAsync( this.variableScriptFile.FilePath); await this.AssertDebuggerStopped(this.variableScriptFile.FilePath).ConfigureAwait(false); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); // TODO: Add checks for correct value strings as well var strVar = variables.FirstOrDefault(v => v.Name == "$strVar"); Assert.NotNull(strVar); Assert.False(strVar.IsExpandable); var objVar = variables.FirstOrDefault(v => v.Name == "$assocArrVar"); Assert.NotNull(objVar); Assert.True(objVar.IsExpandable); var objChildren = debugService.GetVariables(objVar.Id); Assert.Equal(9, objChildren.Length); var arrVar = variables.FirstOrDefault(v => v.Name == "$arrVar"); Assert.NotNull(arrVar); Assert.True(arrVar.IsExpandable); var arrChildren = debugService.GetVariables(arrVar.Id); Assert.Equal(11, arrChildren.Length); var classVar = variables.FirstOrDefault(v => v.Name == "$classVar"); Assert.NotNull(classVar); Assert.True(classVar.IsExpandable); var classChildren = debugService.GetVariables(classVar.Id); Assert.Equal(2, classChildren.Length); // Abort script execution early and wait for completion this.debugService.Abort(); await executeTask.ConfigureAwait(false); }
public async Task DebuggerStopsOnConditionalBreakpoints() { const int breakpointValue1 = 10; const int breakpointValue2 = 20; BreakpointDetails[] breakpoints = await this.debugService.SetLineBreakpointsAsync( this.debugScriptFile, new[] { BreakpointDetails.Create("", 7, null, $"$i -eq {breakpointValue1} -or $i -eq {breakpointValue2}"), }); await this.AssertStateChange(PowerShellContextState.Ready); Task executeTask = this.powerShellContext.ExecuteScriptWithArgsAsync( this.debugScriptFile.FilePath); // Wait for conditional breakpoint to hit await this.AssertDebuggerStopped(this.debugScriptFile.FilePath, 7); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); // Verify the breakpoint only broke at the condition ie. $i -eq breakpointValue1 var i = variables.FirstOrDefault(v => v.Name == "$i"); Assert.NotNull(i); Assert.False(i.IsExpandable); Assert.Equal($"{breakpointValue1}", i.ValueString); // The conditional breakpoint should not fire again, until the value of // i reaches breakpointValue2. this.debugService.Continue(); await this.AssertDebuggerStopped(this.debugScriptFile.FilePath, 7); stackFrames = debugService.GetStackFrames(); variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); // Verify the breakpoint only broke at the condition ie. $i -eq breakpointValue1 i = variables.FirstOrDefault(v => v.Name == "$i"); Assert.NotNull(i); Assert.False(i.IsExpandable); Assert.Equal($"{breakpointValue2}", i.ValueString); // Abort script execution early and wait for completion this.debugService.Abort(); await executeTask; }
public static Breakpoint Create( BreakpointDetails breakpointDetails) { Validate.IsNotNull(nameof(breakpointDetails), breakpointDetails); return(new Breakpoint { Verified = breakpointDetails.Verified, Message = breakpointDetails.Message, Source = breakpointDetails.Source, Line = breakpointDetails.LineNumber, Column = breakpointDetails.ColumnNumber }); }
private void DebugService_BreakpointUpdated(object sender, BreakpointUpdatedEventArgs e) { string reason = "changed"; if (_debugStateService.IsSetBreakpointInProgress) { // Don't send breakpoint update notifications when setting // breakpoints on behalf of the client. return; } switch (e.UpdateType) { case BreakpointUpdateType.Set: reason = "new"; break; case BreakpointUpdateType.Removed: reason = "removed"; break; } var breakpoint = new OmniSharp.Extensions.DebugAdapter.Protocol.Models.Breakpoint { Verified = e.UpdateType != BreakpointUpdateType.Disabled }; if (e.Breakpoint is LineBreakpoint) { breakpoint = LspDebugUtils.CreateBreakpoint(BreakpointDetails.Create(e.Breakpoint)); } else if (e.Breakpoint is CommandBreakpoint) { _logger.LogTrace("Function breakpoint updated event is not supported yet"); return; } else { _logger.LogError($"Unrecognized breakpoint type {e.Breakpoint.GetType().FullName}"); return; } _debugAdapterServer.SendNotification(EventNames.Breakpoint, new BreakpointEvent { Reason = reason, Breakpoint = breakpoint }); }
private async void DebugService_BreakpointUpdatedAsync(object sender, BreakpointUpdatedEventArgs e) { string reason = "changed"; if (_setBreakpointInProgress) { // Don't send breakpoint update notifications when setting // breakpoints on behalf of the client. return; } switch (e.UpdateType) { case BreakpointUpdateType.Set: reason = "new"; break; case BreakpointUpdateType.Removed: reason = "removed"; break; } Protocol.DebugAdapter.Breakpoint breakpoint; if (e.Breakpoint is LineBreakpoint) { breakpoint = Protocol.DebugAdapter.Breakpoint.Create(BreakpointDetails.Create(e.Breakpoint)); } else if (e.Breakpoint is CommandBreakpoint) { //breakpoint = Protocol.DebugAdapter.Breakpoint.Create(CommandBreakpointDetails.Create(e.Breakpoint)); Logger.Write(LogLevel.Verbose, "Function breakpoint updated event is not supported yet"); return; } else { Logger.Write(LogLevel.Error, $"Unrecognized breakpoint type {e.Breakpoint.GetType().FullName}"); return; } breakpoint.Verified = e.UpdateType != BreakpointUpdateType.Disabled; await _messageSender.SendEventAsync( BreakpointEvent.Type, new BreakpointEvent { Reason = reason, Breakpoint = breakpoint }); }
public static Breakpoint CreateBreakpoint( BreakpointDetails breakpointDetails) { Validate.IsNotNull(nameof(breakpointDetails), breakpointDetails); return new Breakpoint { Id = breakpointDetails.Id, Verified = breakpointDetails.Verified, Message = breakpointDetails.Message, Source = new Source { Path = breakpointDetails.Source }, Line = breakpointDetails.LineNumber, Column = breakpointDetails.ColumnNumber }; }
public async Task DebuggerVariableHashtableDisplaysCorrectly() { await this.debugService.SetLineBreakpointsAsync( this.variableScriptFile, new[] { BreakpointDetails.Create(this.variableScriptFile.FilePath, 11) }).ConfigureAwait(false); // Execute the script and wait for the breakpoint to be hit Task executeTask = this.powerShellContext.ExecuteScriptStringAsync( this.variableScriptFile.FilePath); await this.AssertDebuggerStopped(this.variableScriptFile.FilePath).ConfigureAwait(false); StackFrameDetails[] stackFrames = debugService.GetStackFrames(); VariableDetailsBase[] variables = debugService.GetVariables(stackFrames[0].LocalVariables.Id); VariableDetailsBase var = variables.FirstOrDefault(v => v.Name == "$assocArrVar"); Assert.NotNull(var); Assert.Equal("[Hashtable: 2]", var.ValueString); Assert.True(var.IsExpandable); VariableDetailsBase[] childVars = debugService.GetVariables(var.Id); Assert.Equal(9, childVars.Length); Assert.Equal("[0]", childVars[0].Name); Assert.Equal("[1]", childVars[1].Name); var childVarStrs = new HashSet <string>(childVars.Select(v => v.ValueString)); var expectedVars = new[] { "[firstChild, \"Child\"]", "[secondChild, 42]" }; foreach (string expectedVar in expectedVars) { Assert.Contains(expectedVar, childVarStrs); } // Abort script execution early and wait for completion this.debugService.Abort(); await executeTask.ConfigureAwait(false); }
public async Task DebuggerFindsParseableButInvalidSimpleBreakpointConditions() { BreakpointDetails[] breakpoints = await this.debugService.SetLineBreakpoints( this.debugScriptFile, new[] { BreakpointDetails.Create("", 5, column: null, condition: "$i == 100"), BreakpointDetails.Create("", 7, column: null, condition: "$i > 100") }); Assert.Equal(2, breakpoints.Length); Assert.Equal(5, breakpoints[0].LineNumber); Assert.False(breakpoints[0].Verified); Assert.Contains("Use '-eq' instead of '=='", breakpoints[0].Message); Assert.Equal(7, breakpoints[1].LineNumber); Assert.False(breakpoints[1].Verified); Assert.NotNull(breakpoints[1].Message); Assert.Contains("Use '-gt' instead of '>'", breakpoints[1].Message); }
public async Task DebuggerProvidesMessageForInvalidConditionalBreakpoint() { BreakpointDetails[] breakpoints = await this.debugService.SetLineBreakpoints( this.debugScriptFile, new[] { BreakpointDetails.Create("", 5), BreakpointDetails.Create("", 10, column: null, condition: "$i -ez 100") }); Assert.Equal(2, breakpoints.Length); Assert.Equal(5, breakpoints[0].LineNumber); Assert.True(breakpoints[0].Verified); Assert.Null(breakpoints[0].Message); Assert.Equal(10, breakpoints[1].LineNumber); Assert.False(breakpoints[1].Verified); Assert.NotNull(breakpoints[1].Message); Assert.Contains("Unexpected token '-ez'", breakpoints[1].Message); }
private void OnBreakpointUpdated(object sender, BreakpointUpdatedEventArgs e) { // Don't send breakpoint update notifications when setting // breakpoints on behalf of the client. if (_debugStateService.IsSetBreakpointInProgress) { return; } if (e.Breakpoint is LineBreakpoint) { OmniSharp.Extensions.DebugAdapter.Protocol.Models.Breakpoint breakpoint = LspDebugUtils.CreateBreakpoint( BreakpointDetails.Create(e.Breakpoint, e.UpdateType) ); string reason = e.UpdateType switch { BreakpointUpdateType.Set => BreakpointEventReason.New, BreakpointUpdateType.Removed => BreakpointEventReason.Removed, BreakpointUpdateType.Enabled => BreakpointEventReason.Changed, BreakpointUpdateType.Disabled => BreakpointEventReason.Changed, _ => "InvalidBreakpointUpdateTypeEnum" }; _debugAdapterServer.SendNotification( EventNames.Breakpoint, new BreakpointEvent { Breakpoint = breakpoint, Reason = reason } ); } else if (e.Breakpoint is CommandBreakpoint) { _logger.LogTrace("Function breakpoint updated event is not supported yet"); } else { _logger.LogError($"Unrecognized breakpoint type {e.Breakpoint.GetType().FullName}"); } }
public async Task DebuggerSetsAndClearsLineBreakpoints() { BreakpointDetails[] breakpoints = await this.debugService.SetLineBreakpointsAsync( this.debugScriptFile, new[] { BreakpointDetails.Create(this.debugScriptFile.FilePath, 5), BreakpointDetails.Create(this.debugScriptFile.FilePath, 10) }).ConfigureAwait(false); var confirmedBreakpoints = await this.GetConfirmedBreakpoints(this.debugScriptFile).ConfigureAwait(false); Assert.Equal(2, confirmedBreakpoints.Count()); Assert.Equal(5, breakpoints[0].LineNumber); Assert.Equal(10, breakpoints[1].LineNumber); breakpoints = await this.debugService.SetLineBreakpointsAsync( this.debugScriptFile, new[] { BreakpointDetails.Create(this.debugScriptFile.FilePath, 2) }).ConfigureAwait(false); confirmedBreakpoints = await this.GetConfirmedBreakpoints(this.debugScriptFile).ConfigureAwait(false); Assert.Single(confirmedBreakpoints); Assert.Equal(2, breakpoints[0].LineNumber); await this.debugService.SetLineBreakpointsAsync( this.debugScriptFile, Array.Empty <BreakpointDetails>()).ConfigureAwait(false); var remainingBreakpoints = await this.GetConfirmedBreakpoints(this.debugScriptFile).ConfigureAwait(false); Assert.Empty(remainingBreakpoints); // Abort debugger this.debugService.Abort(); }
public async Task DebuggerSetsAndClearsLineBreakpoints() { BreakpointDetails[] breakpoints = await this.debugService.SetLineBreakpoints( this.debugScriptFile, new[] { BreakpointDetails.Create("", 5), BreakpointDetails.Create("", 10) }); var confirmedBreakpoints = await this.GetConfirmedBreakpoints(this.debugScriptFile); Assert.Equal(2, confirmedBreakpoints.Count()); Assert.Equal(5, breakpoints[0].LineNumber); Assert.Equal(10, breakpoints[1].LineNumber); breakpoints = await this.debugService.SetLineBreakpoints( this.debugScriptFile, new[] { BreakpointDetails.Create("", 2) }); confirmedBreakpoints = await this.GetConfirmedBreakpoints(this.debugScriptFile); Assert.Equal(1, confirmedBreakpoints.Count()); Assert.Equal(2, breakpoints[0].LineNumber); await this.debugService.SetLineBreakpoints( this.debugScriptFile, new[] { BreakpointDetails.Create("", 0) }); var remainingBreakpoints = await this.GetConfirmedBreakpoints(this.debugScriptFile); Assert.False( remainingBreakpoints.Any(), "Breakpoints in the script file were not cleared"); }
public async Task DebuggerStopsOnLineBreakpoints() { await this.debugService.SetLineBreakpointsAsync( this.debugScriptFile, new[] { BreakpointDetails.Create(this.debugScriptFile.FilePath, 5), BreakpointDetails.Create(this.debugScriptFile.FilePath, 7) }).ConfigureAwait(false); Task executeTask = this.powerShellContext.ExecuteScriptWithArgsAsync( this.debugScriptFile.FilePath); // Wait for a couple breakpoints await this.AssertDebuggerStopped(this.debugScriptFile.FilePath, 5).ConfigureAwait(false); this.debugService.Continue(); await this.AssertDebuggerStopped(this.debugScriptFile.FilePath, 7).ConfigureAwait(false); // Abort script execution early and wait for completion this.debugService.Abort(); await executeTask.ConfigureAwait(false); }
protected async Task HandleSetBreakpointsRequestAsync( SetBreakpointsRequestArguments setBreakpointsParams, RequestContext <SetBreakpointsResponseBody> requestContext) { ScriptFile scriptFile = null; // When you set a breakpoint in the right pane of a Git diff window on a PS1 file, // the Source.Path comes through as Untitled-X. That's why we check for IsUntitledPath. if (!ScriptFile.IsUntitledPath(setBreakpointsParams.Source.Path) && !_editorSession.Workspace.TryGetFile( setBreakpointsParams.Source.Path, out scriptFile)) { string message = _noDebug ? string.Empty : "Source file could not be accessed, breakpoint not set."; var srcBreakpoints = setBreakpointsParams.Breakpoints .Select(srcBkpt => Protocol.DebugAdapter.Breakpoint.Create( srcBkpt, setBreakpointsParams.Source.Path, message, verified: _noDebug)); // Return non-verified breakpoint message. await requestContext.SendResultAsync( new SetBreakpointsResponseBody { Breakpoints = srcBreakpoints.ToArray() }); return; } // Verify source file is a PowerShell script file. string fileExtension = Path.GetExtension(scriptFile?.FilePath ?? "")?.ToLower(); if (string.IsNullOrEmpty(fileExtension) || ((fileExtension != ".ps1") && (fileExtension != ".psm1"))) { Logger.Write( LogLevel.Warning, $"Attempted to set breakpoints on a non-PowerShell file: {setBreakpointsParams.Source.Path}"); string message = _noDebug ? string.Empty : "Source is not a PowerShell script, breakpoint not set."; var srcBreakpoints = setBreakpointsParams.Breakpoints .Select(srcBkpt => Protocol.DebugAdapter.Breakpoint.Create( srcBkpt, setBreakpointsParams.Source.Path, message, verified: _noDebug)); // Return non-verified breakpoint message. await requestContext.SendResultAsync( new SetBreakpointsResponseBody { Breakpoints = srcBreakpoints.ToArray() }); return; } // At this point, the source file has been verified as a PowerShell script. var breakpointDetails = new BreakpointDetails[setBreakpointsParams.Breakpoints.Length]; for (int i = 0; i < breakpointDetails.Length; i++) { SourceBreakpoint srcBreakpoint = setBreakpointsParams.Breakpoints[i]; breakpointDetails[i] = BreakpointDetails.Create( scriptFile.FilePath, srcBreakpoint.Line, srcBreakpoint.Column, srcBreakpoint.Condition, srcBreakpoint.HitCondition); } // If this is a "run without debugging (Ctrl+F5)" session ignore requests to set breakpoints. BreakpointDetails[] updatedBreakpointDetails = breakpointDetails; if (!_noDebug) { _setBreakpointInProgress = true; try { updatedBreakpointDetails = await _editorSession.DebugService.SetLineBreakpointsAsync( scriptFile, breakpointDetails); } catch (Exception e) { // Log whatever the error is Logger.WriteException($"Caught error while setting breakpoints in SetBreakpoints handler for file {scriptFile?.FilePath}", e); } finally { _setBreakpointInProgress = false; } } await requestContext.SendResultAsync( new SetBreakpointsResponseBody { Breakpoints = updatedBreakpointDetails .Select(Protocol.DebugAdapter.Breakpoint.Create) .ToArray() }); }