public void LocalsBasic(ITestSettings settings) { this.TestPurpose("Check primitives displying in locals."); this.WriteSettings(settings); IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Expression); using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings)) { this.Comment("Configure launch."); runner.Launch(settings.DebuggerSettings, debuggee, "-fExpression"); this.Comment("Set a line breakpoints so that we can stop."); runner.SetBreakpoints(debuggee.Breakpoints(SinkHelper.Expression, 31)); this.Comment("To start debugging and break"); runner.Expects.StoppedEvent(StoppedReason.Breakpoint).AfterConfigurationDone(); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { IFrameInspector currentFrame = threadInspector.Stack.First(); this.Comment("To verify locals variables on current frame."); Assert.Subset(new HashSet <string>() { "mybool", "mychar", "myint", "mywchar", "myfloat", "mydouble", "this" }, currentFrame.Variables.ToKeySet()); currentFrame.AssertVariables( "mybool", "true", "myint", "100"); currentFrame.GetVariable("mychar").AssertValueAsChar('A'); currentFrame.GetVariable("mywchar").AssertValueAsWChar('z'); currentFrame.GetVariable("myfloat").AssertValueAsFloat(299); currentFrame.GetVariable("mydouble").AssertValueAsDouble(321); } this.Comment("Run to completion"); runner.Expects.TerminatedEvent().AfterContinue(); runner.DisconnectAndVerify(); } }
public void RunModeBreakpoints(ITestSettings settings) { this.TestPurpose("Tests setting breakpoints while in run mode"); 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, "-fNonTerminating"); runner.ConfigurationDone(); // Wait a second to ensure the debuggee has entered run mode, then try to set a breakpoint Thread.Sleep(TimeSpan.FromSeconds(1)); this.Comment("Set a function breakpoint while in run mode"); FunctionBreakpoints functionBreakpoints = new FunctionBreakpoints("NonTerminating::DoSleep"); runner.ExpectBreakpointAndStepToTarget(SinkHelper.NonTerminating, startLine: 37, targetLine: 38) .AfterSetFunctionBreakpoints(functionBreakpoints); this.Comment("Remove function breakpoint"); functionBreakpoints.Remove("NonTerminating::DoSleep"); runner.SetFunctionBreakpoints(functionBreakpoints); this.Comment("Continue, set a line breakpoint while in run mode"); runner.Continue(); // Wait a second to ensure the debuggee has entered run mode, then try to set a breakpoint Thread.Sleep(TimeSpan.FromSeconds(1)); runner.Expects.HitBreakpointEvent(SinkHelper.NonTerminating, 28) .AfterSetBreakpoints(debuggee.Breakpoints(SinkHelper.NonTerminating, 28)); this.Comment("Escape loop"); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { IFrameInspector firstFrame = threadInspector.Stack.First(); this.WriteLine(firstFrame.ToString()); firstFrame.GetVariable("this", "shouldExit").Value = "1"; } this.Comment("Continue until end"); runner.Expects.ExitedEvent() .TerminatedEvent() .AfterContinue(); runner.DisconnectAndVerify(); } }
public void AttachAsyncBreak(ITestSettings settings) { this.TestPurpose("Verifies attach and that breakpoints can be set from break mode."); this.WriteSettings(settings); IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Attach); Process debuggeeProcess = debuggee.Launch("-fNonTerminating", "-fCalling"); using (ProcessHelper.ProcessCleanup(this, debuggeeProcess)) using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings)) { this.Comment("Attach to debuggee"); runner.Attach(settings.DebuggerSettings, debuggeeProcess); runner.ConfigurationDone(); this.Comment("Attempt to break all"); StoppedEvent breakAllEvent = new StoppedEvent(StoppedReason.Pause); runner.Expects.Event(breakAllEvent) .AfterAsyncBreak(); this.WriteLine("Break all stopped on:"); this.WriteLine(breakAllEvent.ActualEvent.ToString()); this.Comment("Set breakpoint while breaking code."); runner.SetBreakpoints(debuggee.Breakpoints(SinkHelper.NonTerminating, 28)); this.Comment("Start running after the async break (since we have no idea where we are) and then hit the breakpoint"); runner.Expects.HitBreakpointEvent(SinkHelper.NonTerminating, 28) .AfterContinue(); this.Comment("Evaluate the shouldExit member to true to stop the infinite loop."); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { IFrameInspector firstFrame = threadInspector.Stack.First(); this.WriteLine(firstFrame.ToString()); firstFrame.GetVariable("shouldExitLocal").Value = "true"; } this.Comment("Continue until debuggee exists"); runner.Expects.ExitedEvent(exitCode: 0).TerminatedEvent().AfterContinue(); this.Comment("Verify debugger and debuggee closed"); runner.DisconnectAndVerify(); Assert.True(debuggeeProcess.HasExited, "Debuggee still running."); } }
public void AssignInvalidExpressionToVariable(ITestSettings settings) { this.TestPurpose("Assign an invalid expression to a variable."); this.WriteSettings(settings); IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Expression); using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings)) { this.Comment("Configure launch."); runner.Launch(settings.DebuggerSettings, debuggee, "-fExpression"); this.Comment("Set a breakpoint so that we can stop at a line."); runner.SetBreakpoints(debuggee.Breakpoints(SinkHelper.Expression, 31)); this.Comment("Start debugging and hit breakpoint."); runner.Expects.StoppedEvent(StoppedReason.Breakpoint).AfterConfigurationDone(); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { IFrameInspector currentFrame = threadInspector.Stack.First(); this.Comment("Assign an invalid expression to a variable."); currentFrame.GetVariable("myint").SetVariableValueExpectFailure("39+nonexistingint"); } // Start another inspector to refresh values using (IThreadInspector threadInspector = runner.GetThreadInspector()) { IFrameInspector currentFrame = threadInspector.Stack.First(); this.Comment("Check the value of the variable hasn't been updated."); Assert.Equal("100", currentFrame.GetVariable("myint").Value); } this.Comment("Continue to run to exist."); runner.Expects.TerminatedEvent().AfterContinue(); runner.DisconnectAndVerify(); } }
public void ExecutionAsyncBreak(ITestSettings settings) { this.TestPurpose("Verify break all should work run function"); this.WriteSettings(settings); this.Comment("Open the kitchen sink debuggee for execution tests."); IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Execution); using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings)) { this.Comment("Configure launch"); runner.Launch(settings.DebuggerSettings, debuggee, "-fNonTerminating", "-fCalling"); this.Comment("Try to break all"); StoppedEvent breakAllEvent = new StoppedEvent(StoppedReason.Pause); runner.Expects.Event(breakAllEvent).AfterAsyncBreak(); this.WriteLine("Break all stopped on:"); this.WriteLine(breakAllEvent.ActualEvent.ToString()); this.Comment("Set a breakpoint while breaking code"); runner.SetBreakpoints(debuggee.Breakpoints(SinkHelper.NonTerminating, 28)); this.Comment("Start running after the async break and then hit the breakpoint"); runner.Expects.HitBreakpointEvent(SinkHelper.NonTerminating, 28).AfterContinue(); this.Comment("Evaluate the shouldExit member to true to stop the infinite loop."); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { IFrameInspector firstFrame = threadInspector.Stack.First(); this.WriteLine(firstFrame.ToString()); firstFrame.GetVariable("shouldExit").Value = "true"; } this.Comment("Continue running at the end of application"); runner.Expects.ExitedEvent().TerminatedEvent().AfterContinue(); this.Comment("Verify debugger and debuggee closed"); runner.DisconnectAndVerify(); } }
public void ExecutionStepRecursiveCall(ITestSettings settings) { this.TestPurpose("Verify steps should work when debugging recursive call"); this.WriteSettings(settings); this.Comment("Open the kitchen sink debuggee for execution tests."); IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Execution); using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings)) { this.Comment("Configure launch"); runner.Launch(settings.DebuggerSettings, debuggee, "-fCalling"); this.Comment("Set initial function breakpoints"); FunctionBreakpoints funcBp = new FunctionBreakpoints("Calling::CoreRun()"); runner.SetFunctionBreakpoints(funcBp); this.Comment("Launch and run until hit function breakpoint in the entry of calling"); runner.ExpectBreakpointAndStepToTarget(SinkHelper.Calling, startLine: 47, targetLine: 48).AfterConfigurationDone(); this.Comment("Step over to go to the entry of recursive call"); runner.Expects.HitStepEvent(SinkHelper.Calling, 49).AfterStepOver(); this.Comment("Step in the recursive call"); runner.ExpectStepAndStepToTarget(SinkHelper.Calling, startLine: 25, targetLine: 26).AfterStepIn(); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { this.Comment("Set count = 2"); IFrameInspector currentFrame = threadInspector.Stack.First(); currentFrame.GetVariable("count").Value = "2"; this.Comment("Verify there is only one 'recursiveCall' frames"); threadInspector.AssertStackFrameNames(true, "recursiveCall.*", "Calling::CoreRun.*", "Feature::Run.*", "main.*"); } this.Comment("Step over and then step in the recursive call once again"); runner.Expects.HitStepEvent(SinkHelper.Calling, 29).AfterStepOver(); runner.ExpectStepAndStepToTarget(SinkHelper.Calling, startLine: 25, targetLine: 26).AfterStepIn(); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { this.Comment("Verify there are two 'recursiveCall' frames"); threadInspector.AssertStackFrameNames(true, "recursiveCall.*", "recursiveCall.*", "Calling::CoreRun.*", "Feature::Run.*", "main.*"); this.Comment("Set a source breakpoint in recursive call"); SourceBreakpoints srcBp = debuggee.Breakpoints(SinkHelper.Calling, 26); runner.SetBreakpoints(srcBp); } this.Comment("Step over the recursive call and hit the source breakpoint"); runner.Expects.HitStepEvent(SinkHelper.Calling, 29).AfterStepOver(); runner.Expects.HitBreakpointEvent(SinkHelper.Calling, 26).AfterStepOver(); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { this.Comment("Verify there are three 'recursiveCall' frames"); threadInspector.AssertStackFrameNames(true, "recursiveCall.*", "recursiveCall.*", "recursiveCall.*", "Calling::CoreRun.*", "Feature::Run.*", "main.*"); } this.Comment("Try to step out twice from recursive call"); runner.ExpectStepAndStepToTarget(SinkHelper.Calling, 29, 30).AfterStepOut(); runner.ExpectStepAndStepToTarget(SinkHelper.Calling, 29, 30).AfterStepOut(); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { this.Comment("Verify 'recursiveCall' return back only one frame"); threadInspector.AssertStackFrameNames(true, "recursiveCall.*", "Calling::CoreRun.*", "Feature::Run.*", "main.*"); } this.Comment("Step over from recursive call"); runner.ExpectStepAndStepToTarget(SinkHelper.Calling, 49, 50).AfterStepOver(); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { this.Comment("Verify there is not 'recursiveCall' frame"); threadInspector.AssertStackFrameNames(true, "Calling::CoreRun.*", "Feature::Run.*", "main.*"); } this.Comment("Verify stop debugging"); runner.DisconnectAndVerify(); } }
public void ThreadingBasic(ITestSettings settings) { this.TestPurpose("Test basic multithreading scenario."); this.WriteSettings(settings); IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Threading); using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings)) { this.Comment("Launching debuggee. Run until multiple threads are running."); runner.Launch(settings.DebuggerSettings, debuggee, "-fThreading"); runner.SetBreakpoints(debuggee.Breakpoints(SinkHelper.Threading, 37)); runner.Expects.HitBreakpointEvent() .AfterConfigurationDone(); IEnumerable <IThreadInfo> threads = runner.GetThreads(); List <string> loopCounts = new List <string>(); this.Comment("Inspect threads and find 'loopCount' variable on each worker thread."); this.WriteLine("Threads:"); foreach (var threadInfo in threads) { IThreadInspector threadInspector = threadInfo.GetThreadInspector(); // Don't look at main thread, just workers if (threadInspector.ThreadId == runner.StoppedThreadId) { continue; } this.Comment("Thread '{0}', Id: {1}".FormatInvariantWithArgs(threadInfo.Name, threadInspector.ThreadId)); IFrameInspector threadLoopFrame = threadInspector.Stack.FirstOrDefault(s => s.Name.Contains("ThreadLoop")); // Fail the test if the ThreadLoop frame could not be found if (threadLoopFrame == null) { this.WriteLine("This thread's stack did not contain a frame with 'ThreadLoop'"); this.WriteLine("Stack Trace:"); foreach (var frame in threadInspector.Stack) { this.WriteLine(frame.Name); } continue; } string variables = threadLoopFrame.Variables.ToReadableString(); this.WriteLine("Variables in 'ThreadLoop' frame:"); this.WriteLine(variables); // Put the different loopCounts in a list, so they can be verified order agnostic string loopCountValue = threadLoopFrame.GetVariable("loopCount").Value; this.WriteLine("loopCount = {0}", loopCountValue); loopCounts.Add(loopCountValue); } //Verify all the worker threads were observed Assert.True(loopCounts.Contains("0"), "Could not find thread with loop count 0"); Assert.True(loopCounts.Contains("1"), "Could not find thread with loop count 1"); Assert.True(loopCounts.Contains("2"), "Could not find thread with loop count 2"); Assert.True(loopCounts.Contains("3"), "Could not find thread with loop count 3"); Assert.True(4 == loopCounts.Count, "Expected to find 4 threads, but found " + loopCounts.Count.ToString(CultureInfo.InvariantCulture)); this.Comment("Run to end."); runner.Expects.TerminatedEvent().AfterContinue(); runner.DisconnectAndVerify(); } }