public async Task BreakpointHit_FunctionEvaluation() { string condition = "Hello() == \"Hello, World!\""; using (var app = StartTestApp(debugEnabled: true, methodEvaluation: true)) { Debuggee debuggee = Polling.GetDebuggee(app.Module, app.Version); DebuggerBreakpoint breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.LoopMiddle, condition); // Checks that the breakpoint has a condition. Assert.Equal(breakpoint.Condition, condition); using (HttpClient client = new HttpClient()) { await client.GetAsync(TestApplication.GetLoopUrl(app, 10)); } DebuggerBreakpoint newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Checks that the breakpoint has been hit. Assert.True(newBp.IsFinalState); // Checks that "i" is 0 when the breakpoint is hit. Debugger.V2.StackFrame firstFrame = newBp.StackFrames[0]; DebuggerVariable iVariable = firstFrame.Locals.First(local => local.Name == "i"); Assert.Equal("0", iVariable.Value); } }
public async Task BreakpointHit_FunctionEvaluationNotPerformedForExpression() { string[] expression = { "Hello()" }; using (var app = StartTestApp(debugEnabled: true)) { Debuggee debuggee = Polling.GetDebuggee(app.Module, app.Version); DebuggerBreakpoint breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.LoopMiddle, null, expression); using (HttpClient client = new HttpClient()) { await client.GetAsync(TestApplication.GetLoopUrl(app, 10)); } DebuggerBreakpoint newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Checks that the breakpoint has been hit. Assert.True(newBp.IsFinalState); // However, it should have error status set to true. Assert.True(newBp.Status.IsError); Assert.Contains("Method call for condition or expression evaluation is disabled.", newBp.Status.Description.Format); Assert.Empty(newBp.StackFrames); } }
public async Task BreakpointHit_MultipleExpressions() { string[] expressions = { "testList[3]", "testDictionary[\"Key103\"]" }; using (var app = StartTestApp(debugEnabled: true, methodEvaluation: true)) { Debuggee debuggee = Polling.GetDebuggee(app.Module, app.Version); DebuggerBreakpoint breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.EchoBottomLine, null, expressions); // Checks that the breakpoint has evaluated expression. using (HttpClient client = new HttpClient()) { await client.GetAsync(TestApplication.GetEchoUrl(app, 10)); } DebuggerBreakpoint newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Checks that the breakpoint has been hit. Assert.True(newBp.IsFinalState); // Checks that the expressions have correct values. Assert.Equal(2, newBp.EvaluatedExpressions.Count); Assert.Equal(expressions[1], newBp.EvaluatedExpressions[0].Name); Assert.Equal("3", newBp.EvaluatedExpressions[0].Value); Assert.Equal(expressions[0], newBp.EvaluatedExpressions[1].Name); Assert.Equal("List103", newBp.EvaluatedExpressions[1].Value); } }
public async Task BreakpointHit_IndexerAccessCondition() { int i = 10; string condition = $"testList[1] == \"List{i}1\""; using (var app = StartTestApp(debugEnabled: true)) { Debuggee debuggee = Polling.GetDebuggee(app.Module, app.Version); DebuggerBreakpoint breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.EchoBottomLine, condition); // Checks that the breakpoint has a condition. Assert.Equal(breakpoint.Condition, condition); using (HttpClient client = new HttpClient()) { await client.GetAsync(TestApplication.GetEchoUrl(app, i)); } DebuggerBreakpoint newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Check that the breakpoint has been hit. Assert.True(newBp.IsFinalState); } }
public async Task BreakpointsSet_ConditionMultiple() { // In this tests, 2 of the breakpoints have their conditions satisfied // while 1 does not. int i = 10; using (var app = StartTestApp(debugEnabled: true, methodEvaluation: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint1 = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.EchoBottomLine, $"testList[1] == \"List{i}1\""); var breakpoint2 = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.EchoBottomLine, $"testList[1] == \"List{i}2\""); var breakpoint3 = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.EchoBottomLine, $"testDictionary[Key{i}2] == 2"); using (HttpClient client = new HttpClient()) { await client.GetAsync(TestApplication.GetEchoUrl(app, i)); Assert.Throws <TimeoutException>(() => Polling.GetBreakpoint(debuggee.Id, breakpoint2.Id)); var newBp1 = Polling.GetBreakpoint(debuggee.Id, breakpoint1.Id); Assert.True(newBp1.IsFinalState); var newBp3 = Polling.GetBreakpoint(debuggee.Id, breakpoint3.Id); Assert.True(newBp3.IsFinalState); } } }
public async Task BreakpointsSet_Multiple() { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint1 = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.HelloLine); var breakpoint2 = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.EchoBottomLine); var breakpoint3 = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.PidLine); using (HttpClient client = new HttpClient()) { await client.GetAsync($"{app.AppUrlEcho}/1"); var newBp2 = Polling.GetBreakpoint(debuggee.Id, breakpoint2.Id); Assert.True(newBp2.IsFinalState); await client.GetAsync(app.AppUrlBase); var newBp1 = Polling.GetBreakpoint(debuggee.Id, breakpoint1.Id); Assert.True(newBp1.IsFinalState); await client.GetAsync(app.AppUrlProcessId); var newBp3 = Polling.GetBreakpoint(debuggee.Id, breakpoint3.Id); Assert.True(newBp3.IsFinalState); } } }
public async Task BreakpointHit_AsyncExpression() { string[] expressions = { "testString", "PublicString", "Hello()" }; string testString = "TestMessage"; using (var app = StartTestApp(debugEnabled: true, methodEvaluation: true)) { Debuggee debuggee = Polling.GetDebuggee(app.Module, app.Version); DebuggerBreakpoint breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.AsyncBottomLine, null, expressions); using (HttpClient client = new HttpClient()) { await client.GetAsync($"{app.AppUrlAsync}/{testString}"); } DebuggerBreakpoint retrievedBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Checks that the expressions have correct values. Assert.Equal(3, retrievedBp.EvaluatedExpressions.Count); Assert.Equal(expressions[2], retrievedBp.EvaluatedExpressions[0].Name); Assert.Equal("Hello, World!", retrievedBp.EvaluatedExpressions[0].Value); Assert.Equal(expressions[0], retrievedBp.EvaluatedExpressions[1].Name); Assert.Equal(testString, retrievedBp.EvaluatedExpressions[1].Value); Assert.Equal(expressions[1], retrievedBp.EvaluatedExpressions[2].Name); Assert.Equal((new TestApp.MainController()).PublicString, retrievedBp.EvaluatedExpressions[2].Value); } }
public async Task BreakpointHit_FunctionEvaluationFailure() { string condition = "NonExistentFunc() == \"Hello, World!\""; using (var app = StartTestApp(debugEnabled: true, methodEvaluation: true)) { Debuggee debuggee = Polling.GetDebuggee(app.Module, app.Version); DebuggerBreakpoint breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.LoopMiddle, condition); // Checks that the breakpoint has a condition. Assert.Equal(breakpoint.Condition, condition); using (HttpClient client = new HttpClient()) { await client.GetAsync(TestApplication.GetLoopUrl(app, 10)); } DebuggerBreakpoint newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Checks that the breakpoint has been hit. Assert.True(newBp.IsFinalState); // However, it should have error status set to true. Assert.True(newBp.Status.IsError); Assert.Empty(newBp.StackFrames); } }
/// <summary> /// Starts the test application (Google.Cloud.Diagnostics.Debug.TestApp) and /// gets the average memory usage during requests to <see cref="AppUrlEcho"/> url for /// <see cref="NumberOfRequest"/> requests. /// </summary> /// <param name="debugEnabled">True if the debugger should be attached to the application.</param> /// <param name="breakpointLine">Optional, the line number to set the breakpoint on. If none is set no /// breakpoint will be set.</param> /// <param name="hitBreakpoint">Optional, true if the breakpoint is expected to hit. Defaults to false.</param> /// <param name="condition">Optional, a condition to set on the breakpoint. If none is set /// no condition will be set.</param> /// <param name="getUrl">Optional, a function to get the url to hit. Defaults to /// <see cref="TestApplication.GetEchoUrl(TestApplication, int)"/></param> /// <returns>The average memory usage during requests.</returns> public async Task <double> GetAverageMemoryUsageMBAsync( bool debugEnabled, int?breakpointLine = null, bool hitBreakpoint = false, string condition = null, Func <TestApplication, int, string> getUrl = null) { using (var app = StartTestApp(debugEnabled: debugEnabled)) { var appProcess = await app.GetApplicationProcess(); var debugProcess = app.GetDebuggerProcess(); var agentProcess = app.GetAgentProcess(); var debuggee = debugEnabled ? Polling.GetDebuggee(app.Module, app.Version) : null; int counter = 0; long memory = 0; var cts = new CancellationTokenSource(); var task = Task.Run(() => { while (!cts.IsCancellationRequested) { memory += appProcess.WorkingSet64; if (debugEnabled) { memory += debugProcess.WorkingSet64; memory += agentProcess.WorkingSet64; } counter++; Thread.Sleep(TimeSpan.FromMilliseconds(2)); } }); using (HttpClient client = new HttpClient()) { for (int i = 0; i < NumberOfRequest; i++) { Debugger.V2.Breakpoint breakpoint = null; if (breakpointLine != null) { // Set a breakpoint and wait to ensure the debuggee picks it up. breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, breakpointLine.Value, condition); Thread.Sleep(TimeSpan.FromSeconds(.5)); } await client.GetAsync($"{app.AppUrlEcho}/{i}"); if (breakpointLine != null) { var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id, isFinal: hitBreakpoint); Assert.Equal(hitBreakpoint, newBp.IsFinalState); } } cts.Cancel(); task.Wait(); return((memory / counter / NumberOfRequest) / Math.Pow(2, 20)); } } }
/// <summary> /// Starts the test application (Google.Cloud.Diagnostics.Debug.TestApp) and /// gets the average CPU percentage during requests to <see cref="AppUrlEcho"/> url for /// <see cref="NumberOfRequest"/> requests. /// </summary> /// <param name="debugEnabled">True if the debugger should be attached to the application.</param> /// <param name="breakpointLine">Optional, the line number to set the breakpoint on. If none is set no /// breakpoint will be set.</param> /// <param name="hitBreakpoint">Optional, true if the breakpoint is expected to hit. Defaults to false.</param> /// <param name="condition">Optional, a condition to set on the breakpoint. If none is set /// no condition will be set.</param> /// <param name="getUrl">Optional, a function to get the url to hit. Defaults to /// <see cref="TestApplication.GetEchoUrl(TestApplication, int)"/></param> /// <returns>The average CPU percentage during requests.</returns> private async Task <double> GetAverageCpuPercentAsync( bool debugEnabled, int?breakpointLine = null, bool hitBreakpoint = false, string condition = null, Func <TestApplication, int, string> getUrl = null) { getUrl = getUrl ?? TestApplication.GetEchoUrl; using (var app = StartTestApp(debugEnabled: debugEnabled)) { var appProcess = await app.GetApplicationProcess(); var debugProcess = app.GetDebuggerProcess(); var agentProcess = app.GetAgentProcess(); Stopwatch watch = Stopwatch.StartNew(); var startingAppCpu = appProcess.TotalProcessorTime; var startingDebugCpu = TimeSpan.Zero; var startingAgentCpu = TimeSpan.Zero; if (debugEnabled) { startingDebugCpu = debugProcess.TotalProcessorTime; startingAgentCpu = agentProcess.TotalProcessorTime; } var debuggee = debugEnabled ? Polling.GetDebuggee(app.Module, app.Version) : null; using (HttpClient client = new HttpClient()) { for (int i = 0; i < NumberOfRequest; i++) { Debugger.V2.Breakpoint breakpoint = null; if (breakpointLine != null) { // Set a breakpoint and wait to ensure the debuggee picks it up. breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, breakpointLine.Value, condition); Thread.Sleep(TimeSpan.FromSeconds(.5)); } await client.GetAsync(getUrl(app, i)); if (breakpointLine != null) { var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id, isFinal: hitBreakpoint); Assert.Equal(hitBreakpoint, newBp.IsFinalState); } } var totalCpuTime = appProcess.TotalProcessorTime - startingAppCpu; if (debugEnabled) { totalCpuTime += debugProcess.TotalProcessorTime - startingDebugCpu; totalCpuTime += agentProcess.TotalProcessorTime - startingAgentCpu; } return(totalCpuTime.TotalMilliseconds / watch.ElapsedMilliseconds); } } }
public async Task TestCollection(string collectionName) { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.EchoBottomLine); string collectionKey = "RandomKey"; using (HttpClient client = new HttpClient()) { await client.GetAsync($"{app.AppUrlEcho}/{collectionKey}"); } var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Check that the breakpoint has been hit. Assert.True(newBp.IsFinalState); // Checks that the first frame of the breakpoint contains collection. DebuggerVariable collection = newBp.StackFrames[0].Locals.FirstOrDefault(localVar => localVar.Name == $"test{collectionName}"); Assert.NotNull(collection); Assert.Equal(6, collection.Members.Count); DebuggerVariable collectionCount = collection.Members.FirstOrDefault(member => member.Name == "Count"); Assert.NotNull(collectionCount); Assert.Equal("5", collectionCount.Value); for (int i = 0; i < 5; i += 1) { DebuggerVariable item = collection.Members.FirstOrDefault(member => member.Name == $"[{i}]"); Assert.NotNull(item); if (collectionName == "Dictionary") { DebuggerVariable key = item.Members.FirstOrDefault(member => member.Name == "key"); DebuggerVariable value = item.Members.FirstOrDefault(member => member.Name == "value"); Assert.NotNull(key); Assert.NotNull(value); Assert.Equal($"Key{collectionKey}{i}", key.Value); Assert.Equal($"{i}", value.Value); } else { Assert.Equal($"{collectionName}{collectionKey}{i}", item.Value); } } } }
public async Task MultipleBreakpointsHit_Wait() { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint1 = SetBreakpoint(debuggee.Id, TestApplication.MainClass, TestApplication.HelloLine); var breakpoint2 = SetBreakpoint(debuggee.Id, TestApplication.MainClass, TestApplication.EchoTopLine); // Let the first two breakpoints get picked up by the server before // setting the last one. Thread.Sleep(TimeSpan.FromSeconds(5)); var breakpoint3 = SetBreakpoint(debuggee.Id, TestApplication.MainClass, TestApplication.PidLine); // Sleep for long period to ensure multiple get calls to the Debugger API. Thread.Sleep(_hangingGetTimeout); using (HttpClient client = new HttpClient()) { await client.GetAsync(app.AppUrlBase); } var newBp1 = Polling.GetBreakpoint(debuggee.Id, breakpoint1.Id); Assert.True(newBp1.IsFinalState); // Ensure these breakpoints aren't final. var newBp2 = Polling.GetBreakpoint(debuggee.Id, breakpoint2.Id, isFinal: false); var newBp3 = Polling.GetBreakpoint(debuggee.Id, breakpoint3.Id, isFinal: false); Assert.False(newBp2.IsFinalState); Assert.False(newBp3.IsFinalState); // Sleep for long period to ensure multiple get calls to the Debugger API. Thread.Sleep(_hangingGetTimeout); using (HttpClient client = new HttpClient()) { await client.GetAsync($"{app.AppUrlEcho}/1"); await client.GetAsync(app.AppUrlProcessId); } newBp2 = Polling.GetBreakpoint(debuggee.Id, breakpoint2.Id); newBp3 = Polling.GetBreakpoint(debuggee.Id, breakpoint3.Id); Assert.True(newBp2.IsFinalState); Assert.True(newBp3.IsFinalState); } }
public async Task BreakpointHit() { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.HelloLine); using (HttpClient client = new HttpClient()) { await client.GetAsync(app.AppUrlBase); } var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Check that the breakpoint has been hit. Assert.True(newBp.IsFinalState); } }
public async Task BreakpointHit_AsyncCondition() { string testString = "TestMessage"; string firstCondition = $"PublicString == \"{new TestApp.MainController().PublicString}\""; string secondCondition = "Hello() == \"Hello, World!\""; string thirdCondition = $"testString == \"{testString}\""; using (var app = StartTestApp(debugEnabled: true, methodEvaluation: true)) { Debuggee debuggee = Polling.GetDebuggee(app.Module, app.Version); DebuggerBreakpoint firstBreakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.AsyncBottomLine, firstCondition); DebuggerBreakpoint secondBreakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.AsyncBottomLine, secondCondition); DebuggerBreakpoint thirdBreakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.AsyncBottomLine, thirdCondition); using (HttpClient client = new HttpClient()) { await client.GetAsync($"{app.AppUrlAsync}/{testString}"); } DebuggerBreakpoint retrievedFirstBp = Polling.GetBreakpoint(debuggee.Id, firstBreakpoint.Id); DebuggerBreakpoint retrievedSecondBp = Polling.GetBreakpoint(debuggee.Id, secondBreakpoint.Id); DebuggerBreakpoint retrievedThirdBp = Polling.GetBreakpoint(debuggee.Id, thirdBreakpoint.Id); // Check that the breakpoints has been hit. Assert.True(retrievedFirstBp.IsFinalState); Assert.Null(retrievedFirstBp.Status); Assert.True(retrievedSecondBp.IsFinalState); Assert.Null(retrievedSecondBp.Status); Assert.True(retrievedThirdBp.IsFinalState); Assert.Null(retrievedThirdBp.Status); } }
public async Task BreakpointHit_Wait() { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.HelloLine); // Sleep for long period to ensure multiple get calls to the Debugger API. Thread.Sleep(_hangingGetTimeout); using (HttpClient client = new HttpClient()) { await client.GetAsync(app.AppUrlBase); } var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Check that the breakpoint has been hit. Assert.True(newBp.IsFinalState); } }
public async Task DebuggerDies_AppLives() { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.HelloLine); using (HttpClient client = new HttpClient()) { // Hit the app and ensure the breakpoint has been hit. await client.GetAsync(app.AppUrlBase); var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); Assert.True(newBp.IsFinalState); // Kill the debugger process and agent process. var debugProcess = app.GetDebuggerProcess(); var agentProcess = app.GetAgentProcess(); debugProcess.Kill(); if (!agentProcess.HasExited) { // Killing the agent will kill the debugger and visa versa. // This is just a sanity check that all processes are no // longer running. agentProcess.Kill(); } // Ensure both the agent and debugger have shutdown. Assert.True(debugProcess.HasExited); Assert.True(agentProcess.HasExited); // Ensure the app is still alive. var result = await client.GetAsync(app.AppUrlBase); Assert.Equal("Hello, World!", result.Content.ReadAsStringAsync().Result); } } }
public async Task BreakpointSet_TwoSameLocation() { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint = SetBreakpoint(debuggee.Id, TestApplication.MainClass, TestApplication.HelloLine); var breakpoint2 = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.HelloLine); using (HttpClient client = new HttpClient()) { await client.GetAsync(app.AppUrlBase); var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); Assert.True(newBp.IsFinalState); await client.GetAsync(app.AppUrlBase); var newBp2 = Polling.GetBreakpoint(debuggee.Id, breakpoint2.Id); Assert.True(newBp2.IsFinalState); } } }
public async Task BreakpointHit_Comment() { using (var app = StartTestApp(debugEnabled: true)) { Debuggee debuggee = Polling.GetDebuggee(app.Module, app.Version); DebuggerBreakpoint breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.LoopMiddleComment); using (HttpClient client = new HttpClient()) { await client.GetAsync(TestApplication.GetLoopUrl(app, 10)); } DebuggerBreakpoint newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Check that the breakpoint has been hit. Assert.True(newBp.IsFinalState); // Check that the breakpoint line is at the next line. Assert.Equal(TestApplication.LoopMiddle, newBp.Location.Line); } }
/// <summary> /// Starts the test application (Google.Cloud.Diagnostics.Debug.TestApp) and /// gets the average latency for requests to the <see cref="AppUrlEcho"/> url for /// <see cref="NumberOfRequest"/> requests. /// </summary> /// <param name="debugEnabled">True if the debugger should be attached to the application.</param> /// <param name="breakpointLine">Optional, the line number to set the breakpoint on. If none is set no /// breakpoint will be set.</param> /// <param name="hitBreakpoint">Optional, true if the breakpoint is expected to hit. Defaults to false.</param> /// <param name="condition">Optional, a condition to set on the breakpoint. If none is set /// no condition will be set.</param> /// <param name="getUrl">Optional, a function to get the url to hit. Defaults to /// <see cref="TestApplication.GetEchoUrl(TestApplication, int)"/></param> /// <returns>The average latency of requests to the url.</returns> private async Task <double> GetAverageLatencyAsync( bool debugEnabled, int?breakpointLine = null, bool hitBreakpoint = false, string condition = null, Func <TestApplication, int, string> getUrl = null) { using (var app = StartTestApp(debugEnabled: debugEnabled)) { var debuggee = debugEnabled ? Polling.GetDebuggee(app.Module, app.Version) : null; using (HttpClient client = new HttpClient()) { TimeSpan totalTime = TimeSpan.Zero; for (int i = 0; i < NumberOfRequest; i++) { Debugger.V2.Breakpoint breakpoint = null; if (breakpointLine != null) { // Set a breakpoint and wait to ensure the debuggee picks it up. breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, breakpointLine.Value, condition); Thread.Sleep(TimeSpan.FromSeconds(.5)); } Stopwatch watch = Stopwatch.StartNew(); await client.GetAsync($"{app.AppUrlEcho}/{i}"); totalTime += watch.Elapsed; if (breakpointLine != null) { var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id, isFinal: hitBreakpoint); Assert.Equal(hitBreakpoint, newBp.IsFinalState); } } return(totalTime.TotalMilliseconds / NumberOfRequest); } } }
public async Task AppDies_DebuggerDies() { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.HelloLine); using (HttpClient client = new HttpClient()) { // Hit the app and ensure the breakpoint has been hit. await client.GetAsync(app.AppUrlBase); var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); Assert.True(newBp.IsFinalState); var debugProcess = app.GetDebuggerProcess(); var agentProcess = app.GetAgentProcess(); // Shut down the running application. app.ShutdownApp(); // The loops allows for about 60 seconds total. This is a generous limit, // generally it takes less than 10 seconds. However, it has been observed taking // a lot longer. int counter = 0; while ((!debugProcess.HasExited || !agentProcess.HasExited) && counter++ < 60) { Thread.Sleep(TimeSpan.FromSeconds(1)); } // Ensure both the agent and debugger have shutdown. Assert.True(debugProcess.HasExited); Assert.True(agentProcess.HasExited); } } }
public async Task BreakpointHit_IndexerAccessConditionFailed() { int i = 10; string condition = $"testList[1] == \"List{i}2\""; using (var app = StartTestApp(debugEnabled: true, methodEvaluation: true)) { Debuggee debuggee = Polling.GetDebuggee(app.Module, app.Version); DebuggerBreakpoint breakpoint = SetBreakpointAndSleep( debuggee.Id, TestApplication.MainClass, TestApplication.EchoBottomLine, condition); // Checks that the breakpoint has a condition. Assert.Equal(breakpoint.Condition, condition); using (HttpClient client = new HttpClient()) { await client.GetAsync(TestApplication.GetEchoUrl(app, i)); } Assert.Throws <TimeoutException>(() => Polling.GetBreakpoint(debuggee.Id, breakpoint.Id)); } }
public async Task BreakpointHit_Details() { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.EchoBottomLine); using (HttpClient client = new HttpClient()) { await client.GetAsync($"{app.AppUrlEcho}/1"); } var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Check basic breakpoint values. Assert.True(newBp.IsFinalState); Assert.Equal(DebuggerBreakpoint.Types.Action.Capture, newBp.Action); Assert.Equal(breakpoint.CreateTime, newBp.CreateTime); Assert.Empty(newBp.Expressions); Assert.Empty(newBp.Condition); Assert.True(newBp.FinalTime.ToDateTime() > newBp.CreateTime.ToDateTime()); // Check the stack frames Assert.Equal(20, newBp.StackFrames.Count); // Only check the first one as it's the only one with information we care about. var stackframe = newBp.StackFrames[0]; // Check the function is echo. Assert.Contains($"{typeof(TestApp.MainController).ToString()}.Echo", stackframe.Function); // Check the location is accurate. var location = stackframe.Location; Assert.Equal(TestApplication.EchoBottomLine, location.Line); Assert.Contains("src/Google.Cloud.Diagnostics.Debug/Google.Cloud.Diagnostics.Debug.TestApp/MainController.cs", location.Path); // Two arguments, the param 'message' and 'this'. var arguments = stackframe.Arguments; Assert.Equal(2, arguments.Count); // Check 'this' arg for the class values. var thisArg = arguments.Where(l => l.Name == "this").Single(); Assert.Equal(typeof(TestApp.MainController).ToString(), thisArg.Type); Assert.Equal(5, thisArg.Members.Count); var privateStaticString = thisArg.Members.Where(m => m.Name == "_privateReadOnlyString").Single(); Assert.Equal(typeof(System.String).ToString(), privateStaticString.Type); var publicString = thisArg.Members.Where(m => m.Name == "PublicString").Single(); Assert.Equal(typeof(System.String).ToString(), publicString.Type); Assert.Equal(new TestApp.MainController().PublicString, publicString.Value); // Check 'message' arg. var messageArg = arguments.Where(l => l.Name == "message").Single(); Assert.Equal(typeof(System.String).ToString(), messageArg.Type); Assert.Equal("1", messageArg.Value); // The list, set and dictionary are tested below. var locals = stackframe.Locals; // One of the local variables will be the 'i' from the for loop // but will have a name like value_*. var iLocal = locals.Where(m => m.Value == "5").Single(); Assert.Equal(typeof(System.Int32).ToString(), iLocal.Type); // One of the local variables will be the condition for the for loop // but will have a name like value_*. var condLocal = locals.Where(m => m.Value == "0").Single(); Assert.Equal(typeof(System.Boolean).ToString(), condLocal.Type); // One of the local variables will be the function's return value // but will have a name like value_*. var returnLocal = locals.Where(m => m.Value == "1").Single(); Assert.Equal(typeof(System.String).ToString(), returnLocal.Type); } }
public async Task BreakpointHit_Constant() { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.ConstantBottomLine); using (HttpClient client = new HttpClient()) { await client.GetAsync($"{app.AppConstant}"); } var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); Assert.True(newBp.IsFinalState); // Only check the first one as it's the only one with information we care about. var stackframe = newBp.StackFrames[0]; // Get 'this' arg for the class values so we can check the constant fields. DebuggerVariable thisArg = stackframe.Arguments.Where(l => l.Name == "this").Single(); Assert.Equal(typeof(TestApp.MainController).ToString(), thisArg.Type); // Check the constant fields. var fields = thisArg.Members; // Check constant int field. DebuggerVariable constantIntField = fields.Where(m => m.Name == "ConstantInt").Single(); Assert.Equal(typeof(System.Int32).ToString(), constantIntField.Type); Assert.Equal("10", constantIntField.Value); // Check the constant string field. DebuggerVariable constantStringField = fields.Where(m => m.Name == "ConstantString").Single(); Assert.Equal(typeof(System.String).ToString(), constantStringField.Type); Assert.Equal("ConstantStringField", constantStringField.Value); // Check the constant enum field. DebuggerVariable constantEnumField = fields.Where(m => m.Name == "Tuesday").Single(); Assert.Equal(typeof(DayOfWeek).ToString(), constantEnumField.Type); Assert.Equal("Tuesday", constantEnumField.Value); // Check the constant variables. var locals = stackframe.Locals; // Check the constant integer. DebuggerVariable constantIntVar = locals.Where(m => m.Name == "constInt").Single(); Assert.Equal(typeof(System.Int32).ToString(), constantIntVar.Type); Assert.Equal("5", constantIntVar.Value); // Check the constant double. DebuggerVariable constantDoubleVar = locals.Where(m => m.Name == "constDouble").Single(); Assert.Equal(typeof(System.Double).ToString(), constantDoubleVar.Type); Assert.Equal("3.500000", constantDoubleVar.Value); // Check the constant string. DebuggerVariable constantStringVar = locals.Where(m => m.Name == "constString").Single(); Assert.Equal(typeof(System.String).ToString(), constantStringVar.Type); Assert.Equal("ConstString", constantStringVar.Value); // Check the constant enum. DebuggerVariable constantEnumVar = locals.Where(m => m.Name == "constEnum").Single(); Assert.Equal(typeof(DayOfWeek).ToString(), constantEnumVar.Type); Assert.Equal("Monday", constantEnumVar.Value); } }
public async Task BreakpointHit_Async() { using (var app = StartTestApp(debugEnabled: true)) { var debuggee = Polling.GetDebuggee(app.Module, app.Version); var breakpoint = SetBreakpointAndSleep(debuggee.Id, TestApplication.MainClass, TestApplication.AsyncBottomLine); string testMessage = "testmessage"; using (HttpClient client = new HttpClient()) { await client.GetAsync($"{app.AppUrlAsync}/{testMessage}"); } var newBp = Polling.GetBreakpoint(debuggee.Id, breakpoint.Id); // Check basic breakpoint values. Assert.True(newBp.IsFinalState); Assert.Equal(DebuggerBreakpoint.Types.Action.Capture, newBp.Action); Assert.Equal(breakpoint.CreateTime, newBp.CreateTime); Assert.Empty(newBp.Expressions); Assert.Empty(newBp.Condition); Assert.True(newBp.FinalTime.ToDateTime() > newBp.CreateTime.ToDateTime()); // Only check the first one as it's the only one with information we care about. var stackframe = newBp.StackFrames[0]; // Check the function is async. // TODO(quoct): Currently, the function name is the name of the state machine // so this condition will be false. We have to fix this in the debugger side. // Assert.Contains($"{typeof(TestApp.MainController).ToString()}.Async", stackframe.Function); // Check the location is accurate. var location = stackframe.Location; Assert.Equal(TestApplication.AsyncBottomLine, location.Line); Assert.Contains("src/Google.Cloud.Diagnostics.Debug/Google.Cloud.Diagnostics.Debug.TestApp/MainController.cs", location.Path); // Two arguments, the param 'message' and 'this'. var arguments = stackframe.Arguments; Assert.Equal(2, arguments.Count); // Check 'this' arg for the class values. var thisArg = arguments.Where(l => l.Name == "this").Single(); Assert.Equal(typeof(TestApp.MainController).ToString(), thisArg.Type); Assert.Equal(5, thisArg.Members.Count); var privateStaticString = thisArg.Members.Where(m => m.Name == "_privateReadOnlyString").Single(); Assert.Equal(typeof(System.String).ToString(), privateStaticString.Type); var publicString = thisArg.Members.Where(m => m.Name == "PublicString").Single(); Assert.Equal(typeof(System.String).ToString(), publicString.Type); Assert.Equal(new TestApp.MainController().PublicString, publicString.Value); // Check 'message' arg. var messageArg = arguments.Where(l => l.Name == "message").Single(); Assert.Equal(typeof(System.String).ToString(), messageArg.Type); Assert.Equal(testMessage, messageArg.Value); // There should be 2 local variables. var locals = stackframe.Locals; Assert.Equal(2, locals.Count); // One of the variable should be testInt. var testIntLocal = locals.Where(m => m.Name == "testInt").Single(); Assert.Equal(typeof(System.Int32).ToString(), testIntLocal.Type); Assert.Equal("0", testIntLocal.Value.ToString()); // One of the local variables will be testString with the same value as testMessage. var testStringLocal = locals.Where(m => m.Name == "testString").Single(); Assert.Equal(typeof(System.String).ToString(), testStringLocal.Type); Assert.Equal(testMessage, testStringLocal.Value); } }