Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix LogPoint Issue + Add IgnoreResponseOrder in DAR #1208

Merged
merged 8 commits into from
Aug 31, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/MIDebugEngine/AD7.Impl/AD7Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -541,9 +541,9 @@ internal sealed class AD7BreakpointEvent : AD7StoppingEvent, IDebugBreakpointEve
{
public const string IID = "501C1E21-C557-48B8-BA30-A1EAB0BC4A74";

private IEnumDebugBoundBreakpoints2 _boundBreakpoints;
IDebugBoundBreakpoint2[] _boundBreakpoints;

public AD7BreakpointEvent(IEnumDebugBoundBreakpoints2 boundBreakpoints)
public AD7BreakpointEvent(IDebugBoundBreakpoint2[] boundBreakpoints)
{
_boundBreakpoints = boundBreakpoints;
}
Expand All @@ -552,7 +552,7 @@ public AD7BreakpointEvent(IEnumDebugBoundBreakpoints2 boundBreakpoints)

int IDebugBreakpointEvent2.EnumBreakpoints(out IEnumDebugBoundBreakpoints2 ppEnum)
{
ppEnum = _boundBreakpoints;
ppEnum = new AD7BoundBreakpointsEnum(_boundBreakpoints);
return Constants.S_OK;
}

Expand Down
4 changes: 1 addition & 3 deletions src/MIDebugEngine/Engine.Impl/EngineCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,7 @@ public void OnBreakpoint(DebuggedThread thread, ReadOnlyCollection<object> clien
// should notify each bound breakpoint that it has been hit and evaluate conditions here.
// The sample engine does not support these features.

AD7BoundBreakpointsEnum boundBreakpointsEnum = new AD7BoundBreakpointsEnum(boundBreakpoints);

AD7BreakpointEvent eventObject = new AD7BreakpointEvent(boundBreakpointsEnum);
AD7BreakpointEvent eventObject = new AD7BreakpointEvent(boundBreakpoints);

AD7Thread ad7Thread = (AD7Thread)thread.Client;
Send(eventObject, AD7BreakpointEvent.IID, ad7Thread);
Expand Down
41 changes: 41 additions & 0 deletions test/CppTests/Tests/BreakpointTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,47 @@ public void FunctionBreakpointsBasic(ITestSettings settings)
}
}

[Theory]
[DependsOnTest(nameof(CompileKitchenSinkForBreakpointTests))]
[RequiresTestSettings]
public void LineLogBreakpointsBasic(ITestSettings settings)
{
this.TestPurpose("Tests basic operation of line breakpoints with a LogPoint");
this.WriteSettings(settings);

IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Breakpoint);

using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings))
{
this.Comment("Configure launch");
runner.Launch(settings.DebuggerSettings, debuggee, "-fCalling");

// These keep track of all the breakpoints in a source file
SourceBreakpoints callingBreakpoints = debuggee.Breakpoints(SinkHelper.Calling, 48);

this.Comment("Set initial breakpoints");
runner.SetBreakpoints(callingBreakpoints);

this.Comment("Launch and run until first breakpoint");
runner.Expects.HitBreakpointEvent(SinkHelper.Calling, 48)
.AfterConfigurationDone();

string logMessage = "Log Message";

this.Comment("Set a logpoint while in break mode");
callingBreakpoints.Add(52, null, logMessage);
runner.SetBreakpoints(callingBreakpoints);

this.Comment("Continue til end with newly-added logpoint");
runner.Expects.OutputEvent("^" + logMessage + "\\b", CategoryValue.Console)
.ExitedEvent()
.TerminatedEvent()
.AfterContinue();

runner.DisconnectAndVerify();
}
}

[Theory]
[DependsOnTest(nameof(CompileKitchenSinkForBreakpointTests))]
[RequiresTestSettings]
Expand Down
55 changes: 52 additions & 3 deletions test/DebugAdapterRunner/DebugAdapterCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,19 @@ private byte[] ReadBlockFromStream(Stream stream, Process debugAdapter, int leng
return messageBuffer;
}

private struct ResponsePair
{
/// <summary>
/// Boolean to indicate if this response has a match.
/// </summary>
public bool Seen { get; set; }

/// <summary>
/// The response
/// </summary>
public object Response { get; set; }
}

public override void Run(DebugAdapterRunner runner)
{
// Send the request
Expand All @@ -138,12 +151,38 @@ public override void Run(DebugAdapterRunner runner)
runner.DebugAdapter.StandardInput.Write(request);

// Process + validate responses
List<object> responseList = new List<object>();
List<ResponsePair> responseList = new List<ResponsePair>();
int currentExpectedResponseIndex = 0;
int previousExpectedResponseIndex = 0;

// Loop until we have received as many expected responses as expected
while (currentExpectedResponseIndex < this.ExpectedResponses.Count)
{
// Check if previous messages contained the expected response
if (previousExpectedResponseIndex != currentExpectedResponseIndex)
{
DebugAdapterResponse expected = this.ExpectedResponses[currentExpectedResponseIndex];
foreach (ResponsePair responsePair in responseList)
{
// Make sure we have not seen this response and check to see if it the response we are expecting.
if (!responsePair.Seen && Utils.CompareObjects(expected.Response, responsePair.Response, expected.IgnoreOrder))
WardenGnaw marked this conversation as resolved.
Show resolved Hide resolved
{
expected.Match = responsePair.Response;
WardenGnaw marked this conversation as resolved.
Show resolved Hide resolved
break;
}
}

// We found an expected response from a previous response.
// Continue to next expectedResponse.
if (expected.Match != null)
{
currentExpectedResponseIndex++;
continue;
}
}

previousExpectedResponseIndex = currentExpectedResponseIndex;

string receivedMessage = null;
Exception getMessageExeception = null;
try
Expand Down Expand Up @@ -221,7 +260,6 @@ public override void Run(DebugAdapterRunner runner)
if (dispatcherMessage.type == "event")
{
DispatcherEvent dispatcherEvent = JsonConvert.DeserializeObject<DispatcherEvent>(receivedMessage);
responseList.Add(dispatcherEvent);

if (dispatcherEvent.eventType == "stopped")
{
Expand All @@ -234,18 +272,29 @@ public override void Run(DebugAdapterRunner runner)
expected.Match = dispatcherEvent;
currentExpectedResponseIndex++;
}

responseList.Add(new ResponsePair()
{
Seen = expected.Match != null,
Response = dispatcherEvent
});
}
else if (dispatcherMessage.type == "response")
{
DispatcherResponse dispatcherResponse = JsonConvert.DeserializeObject<DispatcherResponse>(receivedMessage);
responseList.Add(dispatcherResponse);

var expected = this.ExpectedResponses[currentExpectedResponseIndex];
if (Utils.CompareObjects(expected.Response, dispatcherResponse, expected.IgnoreOrder))
{
expected.Match = dispatcherResponse;
currentExpectedResponseIndex++;
}

responseList.Add(new ResponsePair()
{
Seen = expected.Match != null,
Response = dispatcherResponse
});
}
else if (dispatcherMessage.type == "request")
{
Expand Down
20 changes: 11 additions & 9 deletions test/DebuggerTesting/OpenDebug/Commands/SetBreakpointsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ public sealed class SetBreakpointsCommandArgs : JsonValue
{
public sealed class SourceBreakpoint
{
public SourceBreakpoint(int line, int? column, string condition)
public SourceBreakpoint(int line, int? column, string condition, string logMessage)
{
this.line = line;
this.column = column;
this.condition = condition;
this.logMessage = logMessage;
}

public int line;
Expand All @@ -31,6 +33,9 @@ public SourceBreakpoint(int line, int? column, string condition)

[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string condition;

[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string logMessage;
}

public Source source = new Source();
Expand Down Expand Up @@ -58,7 +63,7 @@ public SourceBreakpoints(string sourceRoot, string relativePath)
{
Parameter.ThrowIfNull(sourceRoot, nameof(sourceRoot));
Parameter.ThrowIfNull(relativePath, nameof(relativePath));
this.Breakpoints = new Dictionary<int, string>();
this.Breakpoints = new Dictionary<int, SetBreakpointsCommandArgs.SourceBreakpoint>();
this.RelativePath = relativePath;
this.FullPath = Path.Combine(sourceRoot, relativePath);
}
Expand All @@ -67,11 +72,11 @@ public SourceBreakpoints(string sourceRoot, string relativePath)

#region Add/Remove

public SourceBreakpoints Add(int lineNumber, string condition = null)
public SourceBreakpoints Add(int lineNumber, string condition = null, string logMessage = null)
{
if (this.Breakpoints.ContainsKey(lineNumber))
throw new RunnerException("Breakpoint line {0} already added to file {1}.", lineNumber, this.RelativePath);
this.Breakpoints.Add(lineNumber, condition);
this.Breakpoints.Add(lineNumber, new SetBreakpointsCommandArgs.SourceBreakpoint(lineNumber, null, condition, logMessage));
return this;
}

Expand All @@ -97,7 +102,7 @@ public SourceBreakpoints Remove(int lineNumber)
/// Keep the breakpoint info in a dictionary indexed by line number.
/// Store the condition as the value.
/// </summary>
public IDictionary<int, string> Breakpoints { get; private set; }
public IDictionary<int, SetBreakpointsCommandArgs.SourceBreakpoint> Breakpoints { get; private set; }
}

#endregion
Expand All @@ -112,10 +117,7 @@ public SetBreakpointsCommand(SourceBreakpoints sourceBreakpoints) :
this()
{
this.Args.source.path = sourceBreakpoints.FullPath;
IDictionary<int, string> breakpoints = sourceBreakpoints.Breakpoints;
this.Args.breakpoints = breakpoints.Select(x =>
new SetBreakpointsCommandArgs.SourceBreakpoint(x.Key, null, x.Value)
).ToArray();
this.Args.breakpoints = sourceBreakpoints.Breakpoints.Select(x => x.Value).ToArray();
this.Args.lines = this.Args.breakpoints.Select(x => x.line).ToArray();
}

Expand Down
34 changes: 0 additions & 34 deletions test/DebuggerTesting/OpenDebug/Events/ConsoleEvent.cs

This file was deleted.

43 changes: 43 additions & 0 deletions test/DebuggerTesting/OpenDebug/Events/OutputEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// // Copyright (c) Microsoft. All rights reserved.
// // Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;

namespace DebuggerTesting.OpenDebug.Events
{
public enum CategoryValue
{
Console = 0,
Stdout = 1,
Stderr = 2,
Telemetry = 3,
Unknown = Int32.MaxValue
}

public sealed class OutputEventValue : EventValue
{
public sealed class Body
{
public string output;

public string category;
}

public Body body = new Body();
}

public sealed class OutputEvent : Event<OutputEventValue>
{
public OutputEvent(string text, CategoryValue category) : base("output")
{
this.ExpectedResponse.body.category = GetCategory(category);
this.ExpectedResponse.body.output = text;
WardenGnaw marked this conversation as resolved.
Show resolved Hide resolved
}

private static string GetCategory(CategoryValue category)
{
Parameter.ThrowIfIsInvalid(category, CategoryValue.Unknown, nameof(category));
return category.ToString().ToLowerInvariant();
}
}
}
4 changes: 2 additions & 2 deletions test/DebuggerTesting/OpenDebug/RunBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ public static IRunBuilder FunctionBreakpointChangedEvent(this IRunBuilder runBui
return runBuilder.Event(new BreakpointEvent(reason, startLine, endLine));
}

public static IRunBuilder ConsoleEvent(this IRunBuilder runBuilder, string text)
public static IRunBuilder OutputEvent(this IRunBuilder runBuilder, string text, CategoryValue category)
{
return runBuilder.Event(new ConsoleEvent(text));
return runBuilder.Event(new OutputEvent(text, category));
}

#endregion
Expand Down